前言
SELECT 可以說是 SQL 最常用的語句了,下面來看一下 SELECT 的基本使用方法。
查詢列
SELECT 列名稱 FROM 表名稱
起別名
使用AS關鍵字
SELECT name AS n
去除重復行
使用DISTINCT關鍵字
SELECT DISTINCT 列名稱 FROM 表名稱
使用DISTINCT需要注意的兩個點:
- DISTINCT 需要放到所有列名的前面。
- DISTINCT其實是對后面所有列名的組合進行去重。
排序檢索數據
使用ORDER BY需要掌握以下幾個點:
- 排序的列名:ORDER BY后面可以有一個或多個列名,多個列名排序時,會按照第一個列先進行排序
- 排序的順序:ORDER BY后面可以注明排序規則,ASC代表遞增排序,DESC代表遞減排序。默認時按照ASC遞增排序。
- 非選擇列排序:ORDER BY可以使用非選擇列進行排序,即使在SELECT后面沒有這個列名,同樣可以放到OEDER BY后面進行排序。
約束返回結果的數量
使用LIMIT關鍵字
SELECT 列名稱 FROM 表名稱 LIMIT 5
SELECT 的執行順序
SELECT 查詢時的兩個順序:
- 關鍵字的順序不能顛倒:
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
- SELECT 語句的執行順序:
FROM > WHERE > GROUP BY > HAVING > SELECT 的字段 > DISTINCT > ORDER BY > LIMIT
SELECT DISTINCT player_id, player_name, count(*) as num # 順序 5
FROM player JOIN team ON player.team_id = team.team_id # 順序 1
WHERE height > 1.80 # 順序 2
GROUP BY player.team_id # 順序 3
HAVING num > 2 # 順序 4
ORDER BY num DESC # 順序 6
LIMIT 2 # 順序 7
SQL 的執行原理
SELECT 先執行 FROM 這一步的。在這個階段,如果是多張表聯查,還會經歷下面的幾個步驟:
-
首先先通過 CROSS JOIN 求笛卡爾積,相當於得到虛擬表 vt(virtual table)1-1;
-
通過 ON 進行篩選,在虛擬表 vt1-1 的基礎上進行篩選,得到虛擬表 vt1-2;
-
添加外部行。如果我們使用的是左連接、右鏈接或者全連接,就會涉及到外部行,也就是在虛擬表 vt1-2 的基礎上增加外部行,得到虛擬表 vt1-3。
如果操作的是兩張以上的表,還會重復上面的步驟,直到所有表都被處理完為止。這個過程得到是原始數據。
當拿到了查詢數據表的原始數據,也就是最終的虛擬表 vt1,就可以在此基礎上再進行 WHERE 階段。在這個階段中,會根據 vt1 表的結果進行篩選過濾,得到虛擬表 vt2。
然后進入第三步和第四步,也就是 GROUP 和 HAVING 階段。在這個階段中,實際上是在虛擬表 vt2 的基礎上進行分組和分組過濾,得到中間的虛擬表 vt3 和 vt4。
當完成了條件篩選部分之后,就可以篩選表中提取的字段,也就是進入到 SELECT 和 DISTINCT 階段。
首先在 SELECT 階段會提取想要的字段,然后在 DISTINCT 階段過濾掉重復的行,分別得到中間的虛擬表 vt5-1 和 vt5-2。
當提取了想要的字段數據之后,就可以按照指定的字段進行排序,也就是 ORDER BY 階段,得到虛擬表 vt6。
最后在 vt6 的基礎上,取出指定行的記錄,也就是 LIMIT 階段,得到最終的結果,對應的是虛擬表 vt7。
當然在寫 SELECT 語句的時候,不一定存在所有的關鍵字,相應的階段就會省略。
關於SELECT *
如果只是練習或者對數據表進行探索,可以使用SELECT *。
生產環境盡量避免使用SELECT *進行查詢。