MySQL 24小時入門筆記(2),查詢

MySQL 24小時入門筆記(2)

查詢

SELECT

SELECT是一個特殊的關鍵字,它的語義是查詢,取出結果。正則表達式

注意:僅爲我的理解。數據庫

FROM

FROM子句,標識要查詢的對象的來源,來源多是多個的。在查詢有多個來源表的狀況下,稱之爲聯結查詢(Join query)。性能

最多見的常規寫法是SELECT column FROM table,表示從特定表取出全部行的特定列。優化

WHERE

WHERE子句用於過濾查詢的行,只有知足條件的行會被查詢出來。spa

常見的用法有SELECT column FROM table WHERE column <> 0,表示在table表中查詢column非空的行,返回這些行的columncode

其中的二元關係運算符<>表示不等於,其餘常見的關係運算符還有這些。對象

運算符 含義
= 相等
> 大於
< 小於
>= 大於等於
<= 小於等於
!= 不等於
<> 不等於

此外還有一些SQL關鍵字能夠輔助編寫判斷邏輯。排序

SQL關鍵字IN能夠用於判斷元素是否在集合中。舉例,SELECT 1 IN (1,2,3),查詢1是否在1,2,3這個集合中。被判斷的集合須要被小括號包圍,而且以逗號分隔元素。索引

SQL關鍵字BETWEEN能夠判斷元素是否在必定區間中。舉例,SELECT 1 BETWEEN 0 and 10,查詢1是否在010的區間內。語法是BETWEEN [low] AND [high],區間較小的一端必須在左側,較大的一端必須在右側。開發

SQL關鍵字LIKE能夠用很是簡單的通配符來判斷元素是否匹配必定的規則。舉例,SELECT 'abcabcabc' LIKE '%CAB%',判斷字符串abcabcabc是否匹配%CAB%。值得注意的是,模式串中的%表明的是匹配0或任意多個字符,就像是正則表達式中的*同樣。此外還有_,下劃線,匹配1個任意字符。

MySQL擴展的REGEXP能夠用正則表達式來匹配元素是否符合模式串。舉例,SELECT 'abcabcabc' REGEXP '.*cab.*',正則表達式不作贅述,簡單的模式串你們都會寫。

ORDER BY

ORDER BY就像字面意義上說的那樣,按照某個列來進行排序。舉例來講,我有一個學生表,記錄了學號和姓名,我能夠按照學號排序。

SELECT * FROM students ORDER BY id;

默認排序是升序,也能夠經過指定DESC或者ASC來決定怎麼排。ASC是升序,DESC是降序。

SELECT * FROM students ORDER BY id DESC;

AS

AS常見的用法是創建別名。

SELECT column AS id_alias FROM my_table AS table_alias WHERE table_alias.column <> 1;

這裏出現了一個新的語法細節,table_alias.column。用點.鏈接表名和列名的行爲相似於C++中的

typedef table_alias = my_table;
auto id_alias = SELECT(table_alias::column, table_alias::column != 0);

看得出來,table_alias.column是徹底限定了column是哪一個column,之因此有這種語法,是由於FROM子句須要支持多個表做爲查詢來源。到時候可能就會用到table1.column <> 1 AND table2.column <> 2這樣的寫法了。

而查詢開頭的column AS id_alias則是標識查詢結果列叫作id_alias,舉例如子查詢的狀況下,便於引用。

JOIN

JOIN的術語叫作聯結,使用了JOIN關鍵字的查詢叫作聯結查詢

聯結查詢和通常的查詢不一樣的地方是,聯結查詢的數據來源是多個表。

最簡單的聯結查詢是內聯結查詢。

舉例來講,我如今有表students以下,全部學生根據超能力開發等級分配到多個班級。

id name class
1 stu1 1
2 stu2 2
3 stu3 3
4 stu4 4

又有表top_class,收錄了全部接收高等級超能力者的班級,能進入這些班級的學生都是如同能考上985211般恐怖如斯的存在。

id name
1 Lv 5
2 Lv 4
3 Lv 3

如今咱們要查詢出學生中那些恐怖如斯的存在有哪些。

SELECT students.name AS name FROM students INNER JOIN top_class ON top_class.id = students.class;

語法JOIN [表] ON [條件]也很簡單啦。在例子中,JOIN表示要聯結表top_classON表示查詢的對象要符合條件top_class.id = students.class。很差理解?看看僞代碼。

for(auto student : students) { // 先過濾 students 表自己,這個過濾應該由 WHERE 子句完成
  for(auto cls : top_class) { // 而後聯結表 top_class
    if(student.cls = cls.id) // 判斷 ON students.class = top_class.id
      results.push(student); // 得出結果
  }
}

注意,僞代碼的查詢過程是錯誤的,爲了方便理解 students.class = top_class.id 才這麼寫。真實數據庫實現聯結查詢的方法應當查閱對應DBMS的文檔。

注意的關鍵點有ON很像但不一樣於WHERE,在瞭解LEFT JOINRIGHT JOIN時會區分。

LEFT JOIN

LEFT JOIN又叫左聯結,基本思路是寫在LEFT JOIN左邊的表知足條件便可做爲結果,即便右邊的表沒有知足條件的條目。

仍是以上文的學園都市數據庫爲例(我tm寫了什麼…)

學生表 students

id name class
1 stu1 1
2 stu2 2
3 stu3 3
4 stu4 4

班級表 top_class

id name
1 Lv 5
2 Lv 4
3 Lv 3

如今咱們查詢學生都處在哪些班級,獲得班級的名字。

SELECT students.name as name, top_class.name as cls
       FROM students LEFT JOIN top_class 
            ON top_class.id = students.class;

查詢結果應該是這樣子的。

name cls
stu1 Lv 5
stu2 Lv 4
stu3 Lv 3
stu4 NULL

注意到了嗎?stu4雖然不是top_class的學生,可是仍是被查詢出來了。

RIGHT JOIN

繼續拿學園都市作例子……

實際上是和左聯結一個鳥樣。

SELECT students.name as name, top_class.name as cls
       FROM top_class RIGHT JOIN students 
            ON top_class.id = students.class;

咱們注意到……我就是把 studentstop_class換了個位置。查詢結果實際上是同樣的。

name cls
stu1 Lv 5
stu2 Lv 4
stu3 Lv 3
stu4 NULL

CROSS JOIN

交叉聯結,查詢結果是聯結的表和FROM的表的笛卡爾積,這麼說聽的明白不?聽不明白就算了,由於交叉聯結基本用不到。

其實就是把兩個表的每一個行都排列組合一下:

  • 表A行1-表B行1
  • 表A行1-表B行2
  • ……
  • 表A行10-表B行1
  • 表A行10-表B行2
  • 表A行10-表B行3
  • ……

JOIN 本身?

術語叫自聯結,其實也挺好理解的,直接舉個例子看看。

id name class
1 stu1 1
2 stu2 1
3 stu3 2
4 stu4 2

注意我數據改了哈。

如今要查詢出全部和stu1同一個班級的學生。

通常咱們想怎麼查?先查出stu1是哪一個班級的:SELECT class FROM students WHERE name = 'stu1',而後查出全部屬於這個班級的學生:SELECT name FROM students WHERE class = [上次查出來的班級]

那麼…怎麼寫成一句話呢?

這時候自聯結就能夠上場了。

SELECT s1.id, s1.name, s1.class
FROM students AS s1 INNER JOIN students AS s2 
WHERE s1.class = s2.class 
    AND s2.name = 'stu1';

查詢結果是

id name class
1 stu1 1
2 stu2 1

基本思路是這樣的:FROM的表是s1,所以INNER JOIN查詢結果來自s1而不是s2。查找s1表中每一個行的classs2表裏有沒有行具備一樣的class屬性,同時,s2具備和s1一樣class屬性的行還必須有個stu1name

分析得知,s2中有stu1這個name的行只有1,因此s2表其實長這樣。

id name class
1 stu1 1

這時候再去看s1表,s1表的class同時存在於s2表的行只有12了。

OUTER JOIN

其實OUTER JOIN上面的LEFT JOINRIGHT JOIN已經講過了,LEFT JOIN的完整寫法就是LEFT OUTER JOINRIGHT JOIN就是RIGHT OUTER JOIN,和INNER JOIN的區別在於OUTER JOIN包含了指定表裏不知足ON條件的行。

這有個知識點,就是ON條件不過濾指定OUTER JOIN的表的不知足條件的行,可是WHERE會過濾。

UNION

UNION關鍵字的術語是聯合查詢

做用是將多個SELECT的結果放在一塊兒並返回。

舉個例子……咱們要查詢全美最好的大學american_top_college和中國最好的大學chinese_top_college數據,來決定報考哪一個大學(反正都考不上),若是不想寫成兩句SELECT,而後手工合併成一個表格的話,那麼就用UNION查詢吧。

SELECT 'american' AS nation, american_top_college.name AS college_name, american_top_college.score_line AS score_line 
FROM american_top_college
UNION
SELECT 'china' AS nation, chinese_top_college.name AS college_name, chinese_top_college.score_line AS score_line;

查詢結果…不展現了。

還有個細節可能要注意,若是有大學同時是美國大學和中國大學的話,那麼爲了在聯合查詢中排除相同的項目,可使用UNION ALL而不是UNION

FULLTEXT

MySQL支持一種實用的文本索引方式,叫作全文本搜索。你們都知道,正則表達式和簡單通配符來查找文本是很是消耗性能的操做,並且難以優化(反正我想不出任何減小查詢的優化思路)。MySQL提供了全文本搜索的屬性來幫助索引文本(可是想到中文支持我以爲已經涼的差很少了),快速查詢出包含特定詞彙之類的行。

抱歉我以爲不行。不說別的,中文分詞就……

跳過了跳過了。

相關文章
相關標籤/搜索