SELECT
是一個特殊的關鍵字,它的語義是查詢,取出結果。正則表達式
注意:僅爲我的理解。數據庫
FROM
子句,標識要查詢的對象的來源,來源多是多個的。在查詢有多個來源表的狀況下,稱之爲聯結查詢(Join query
)。性能
最多見的常規寫法是SELECT column FROM table
,表示從特定表取出全部行的特定列。優化
WHERE
子句用於過濾查詢的行,只有知足條件的行會被查詢出來。spa
常見的用法有SELECT column FROM table WHERE column <> 0
,表示在table
表中查詢column
非空的行,返回這些行的column
。code
其中的二元關係運算符<>
表示不等於,其餘常見的關係運算符還有這些。對象
運算符 | 含義 |
---|---|
= |
相等 |
> |
大於 |
< |
小於 |
>= |
大於等於 |
<= |
小於等於 |
!= |
不等於 |
<> |
不等於 |
此外還有一些SQL
關鍵字能夠輔助編寫判斷邏輯。排序
SQL
關鍵字IN
能夠用於判斷元素是否在集合中。舉例,SELECT 1 IN (1,2,3)
,查詢1
是否在1,2,3
這個集合中。被判斷的集合須要被小括號包圍,而且以逗號分隔元素。索引
SQL
關鍵字BETWEEN
能夠判斷元素是否在必定區間中。舉例,SELECT 1 BETWEEN 0 and 10
,查詢1
是否在0
到10
的區間內。語法是BETWEEN [low] AND [high]
,區間較小的一端必須在左側,較大的一端必須在右側。開發
SQL
關鍵字LIKE
能夠用很是簡單的通配符來判斷元素是否匹配必定的規則。舉例,SELECT 'abcabcabc' LIKE '%CAB%'
,判斷字符串abcabcabc
是否匹配%CAB%
。值得注意的是,模式串中的%
表明的是匹配0或任意多個字符,就像是正則表達式中的*
同樣。此外還有_
,下劃線,匹配1個任意字符。
MySQL
擴展的REGEXP
能夠用正則表達式來匹配元素是否符合模式串。舉例,SELECT 'abcabcabc' REGEXP '.*cab.*'
,正則表達式不作贅述,簡單的模式串你們都會寫。
ORDER BY
就像字面意義上說的那樣,按照某個列來進行排序。舉例來講,我有一個學生表,記錄了學號和姓名,我能夠按照學號排序。
SELECT * FROM students ORDER BY id;
默認排序是升序,也能夠經過指定DESC
或者ASC
來決定怎麼排。ASC
是升序,DESC
是降序。
SELECT * FROM students ORDER BY id DESC;
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
關鍵字的查詢叫作聯結查詢。
聯結查詢和通常的查詢不一樣的地方是,聯結查詢的數據來源是多個表。
最簡單的聯結查詢是內聯結查詢。
舉例來講,我如今有表students
以下,全部學生根據超能力開發等級分配到多個班級。
id | name | class |
---|---|---|
1 | stu1 | 1 |
2 | stu2 | 2 |
3 | stu3 | 3 |
4 | stu4 | 4 |
又有表top_class
,收錄了全部接收高等級超能力者的班級,能進入這些班級的學生都是如同能考上985
、211
般恐怖如斯的存在。
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_class
,ON
表示查詢的對象要符合條件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 JOIN
和RIGHT 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
的學生,可是仍是被查詢出來了。
繼續拿學園都市作例子……
實際上是和左聯結一個鳥樣。
SELECT students.name as name, top_class.name as cls FROM top_class RIGHT JOIN students ON top_class.id = students.class;
咱們注意到……我就是把 students
和 top_class
換了個位置。查詢結果實際上是同樣的。
name | cls |
---|---|
stu1 | Lv 5 |
stu2 | Lv 4 |
stu3 | Lv 3 |
stu4 | NULL |
交叉聯結,查詢結果是聯結的表和FROM
的表的笛卡爾積,這麼說聽的明白不?聽不明白就算了,由於交叉聯結基本用不到。
其實就是把兩個表的每一個行都排列組合一下:
術語叫自聯結,其實也挺好理解的,直接舉個例子看看。
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
表中每一個行的class
在s2
表裏有沒有行具備一樣的class
屬性,同時,s2
具備和s1
一樣class
屬性的行還必須有個stu1
的name
。
分析得知,s2
中有stu1
這個name
的行只有1
,因此s2
表其實長這樣。
id | name | class |
---|---|---|
1 | stu1 | 1 |
這時候再去看s1
表,s1
表的class
同時存在於s2
表的行只有1
和2
了。
其實OUTER JOIN
上面的LEFT JOIN
和RIGHT JOIN
已經講過了,LEFT JOIN
的完整寫法就是LEFT OUTER JOIN
,RIGHT JOIN
就是RIGHT OUTER JOIN
,和INNER JOIN
的區別在於OUTER JOIN
包含了指定表裏不知足ON
條件的行。
這有個知識點,就是ON
條件不過濾指定OUTER JOIN
的表的不知足條件的行,可是WHERE
會過濾。
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
。
MySQL
支持一種實用的文本索引方式,叫作全文本搜索。你們都知道,正則表達式和簡單通配符來查找文本是很是消耗性能的操做,並且難以優化(反正我想不出任何減小查詢的優化思路)。MySQL
提供了全文本搜索的屬性來幫助索引文本(可是想到中文支持我以爲已經涼的差很少了),快速查詢出包含特定詞彙之類的行。
抱歉我以爲不行。不說別的,中文分詞就……
跳過了跳過了。