SQL語句書寫順序和執行順序
(7) SELECT
(8) DISTINCT <select_list>
(1) FROM <main_table>
(3) <join_type> JOIN <join_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>
書寫順序從上向下依次書寫,即:
SELECT →FROM → JOIN → ON → WHERE → GROUP BY → HAVING → ORDER BY→ LIMIT
而執行順序按照左側編號進行。即:
FROM → ON → JOIN → WHERE → GROUP BY → HAVING → SELECT →DISTINCT → ORDER BY→ LIMIT
MySql執行順序理解
-
加載 from關鍵詞后面跟的表,計算笛卡爾積,生成虛擬表vt1。這也是sql執行的第一步:表示要從數據庫中執行哪些表。
-
篩選關聯表中滿足on表達式的數據,保留主表數據,並生成虛擬表vt2。join表示要關聯的表,on代表連接條件。
-
如果使用的是外連接,執行on的時候,會將主表中不符合on條件的數據也加載進來,作為外部行。
-
如果from子句中涉及多張表,則重復第一步到第三步,直至所有的表都加載完畢,更新vt3。
-
執行where表達式,篩選出符合條件的數據生成vt4。
-
執行 group by 子句進行分組。分組會把子句組合成唯一值並且每個唯一值只包含一行,生成vt5。一旦執行group by,后面的所有步驟只能操作vt5中的列(group by的子句包含的列)和聚合函數。
溫馨提示:這一步開始才可以使用select中的別名,它返回的是一個游標,而不是一張表,所以在where中不可以使用select中的別名,而having卻可以。 -
執行聚合函數,例如sum、avg等,生成vt6。
-
執行having表達式,篩選vt6中的數據。having是唯一一個可以在分組后執行的條件篩選表達式,生成vt7。
-
執行SELECT,從vt7中篩選列,生成vt8。
-
執行distinct,對vt8去重,生成vt9。
其實執行過group by后就沒必要再去執行distinct,因為分組后,每組只會有一條數據,並且每條數據都不相同。 -
按照order_by_condition 對vt9進行排序,此處亦可以使用別名。這個過程比較耗費資源。
-
執行 limit 語句,取出指定條數的結果集返回給客戶端。
實例
select g.student_id, sum(成績) as sum成績
from t_grade g INNER JOIN t_student s on g.student_id = s.id
where s.clasz = '高一1班'
group by g.student_id
having sum成績 > 600
order by sum成績
在上面的MySQL代碼示例中,SQL 語句的執行順序如下:
-
首先執行 FROM 子句, 從表 t_grade 和 t_student 組裝數據源的數據,執行一個笛卡爾乘積,此時生成虛擬表 vt1。
-
接下來便是應用on篩選器,on 中的邏輯表達式將應用到 vt1 中的各個行,篩選出滿足 on 邏輯表達式的結果集,生成虛擬表 vt2。
-
由於是 inner join,故把兩張表過濾的行添加進來,生成虛擬表vt3。
-
執行 WHERE 子句, 篩選 vt3中高一1班所有數據。
-
執行 GROUP BY 子句, 按 student_id 列進行分組。
溫馨提示:這一步開始才可以使用select中的別名,它返回的是一個游標,而不是一張表,所以在where中不可以使用select中的別名,而having卻可以。 -
使用聚合函數 sum() 計算各位同學的總成績。
-
執行 HAVING 子句, 篩選課程總成績大於 600 分的學生。
知識擴展
on和where的區別
簡單地說,當有外關聯表時,on主要是針對外關聯表進行篩選,主表保留;當不是外關聯表時,二者作用相同。例如在左外連時,首先執行on,篩選掉外連表中不符合on表達式的數據,而where的篩選是對on關聯后的結果集進行篩選。
limit 分頁
若每頁顯示條目數記為pageSize,顯示的頁數記為page,則有:
SELECT * FROM table_name LIMIT (page-1)* pageSize, pageSize
結束語
了解了MySQL中SQL的執行順序,對我們開發者大有裨益,可以寫出更健壯的代碼。
本文總結了mysql的書寫順序和執行順序,理解這些有助於優化sql語句,有助於掌握 MySQL 中的 sql 語句從寫出來到最終執行的軌跡,有助於深入和細致的認識 sql,提高數據庫理解能力。同時,對於復雜sql的執行過程、編寫都會有一定程度的意義。
以上就是這篇文章的全部內容了,希望本文對大家的學習或者工作具有一定的參考和學習價值;如果有疑問,大家可以在評論區留言交流,也希望大家多多點贊關注。謝謝大家對樓蘭的胡楊的支持!