MySQL SQL語句書寫順序和執行順序


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執行順序理解

  1. 加載 from關鍵詞后面跟的表,計算笛卡爾積,生成虛擬表vt1。這也是sql執行的第一步:表示要從數據庫中執行哪些表。

  2. 篩選關聯表中滿足on表達式的數據,保留主表數據,並生成虛擬表vt2。join表示要關聯的表,on代表連接條件。

  3. 如果使用的是外連接,執行on的時候,會將主表中不符合on條件的數據也加載進來,作為外部行。

  4. 如果from子句中涉及多張表,則重復第一步到第三步,直至所有的表都加載完畢,更新vt3。

  5. 執行where表達式,篩選出符合條件的數據生成vt4。

  6. 執行 group by 子句進行分組。分組會把子句組合成唯一值並且每個唯一值只包含一行,生成vt5。一旦執行group by,后面的所有步驟只能操作vt5中的列(group by的子句包含的列)和聚合函數。
         溫馨提示:這一步開始才可以使用select中的別名,它返回的是一個游標,而不是一張表,所以在where中不可以使用select中的別名,而having卻可以。

  7. 執行聚合函數,例如sum、avg等,生成vt6。

  8. 執行having表達式,篩選vt6中的數據。having是唯一一個可以在分組后執行的條件篩選表達式,生成vt7。

  9. 執行SELECT,從vt7中篩選列,生成vt8。

  10. 執行distinct,對vt8去重,生成vt9。
         其實執行過group by后就沒必要再去執行distinct,因為分組后,每組只會有一條數據,並且每條數據都不相同。

  11. 按照order_by_condition 對vt9進行排序,此處亦可以使用別名。這個過程比較耗費資源。

  12. 執行 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 語句的執行順序如下:

  1. 首先執行 FROM 子句, 從表 t_grade 和 t_student 組裝數據源的數據,執行一個笛卡爾乘積,此時生成虛擬表 vt1。

  2. 接下來便是應用on篩選器,on 中的邏輯表達式將應用到 vt1 中的各個行,篩選出滿足 on 邏輯表達式的結果集,生成虛擬表 vt2。

  3. 由於是 inner join,故把兩張表過濾的行添加進來,生成虛擬表vt3。

  4. 執行 WHERE 子句, 篩選 vt3中高一1班所有數據。

  5. 執行 GROUP BY 子句, 按 student_id 列進行分組。
    溫馨提示:這一步開始才可以使用select中的別名,它返回的是一個游標,而不是一張表,所以在where中不可以使用select中的別名,而having卻可以。

  6. 使用聚合函數 sum() 計算各位同學的總成績。

  7. 執行 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的執行過程、編寫都會有一定程度的意義。

     以上就是這篇文章的全部內容了,希望本文對大家的學習或者工作具有一定的參考和學習價值;如果有疑問,大家可以在評論區留言交流,也希望大家多多點贊關注。謝謝大家對樓蘭的胡楊的支持!

Reference

  1. https://blog.51cto.com/13593129/2357192?source=dra
  2. https://www.cnblogs.com/liangbaikai00/p/13392695.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM