MySQL查詢SQL語句的執(zhí)行順序的方法
標(biāo)準(zhǔn)執(zhí)行順序
MySQL在執(zhí)行一條SELECT查詢時(shí),邏輯上的執(zhí)行順序如下:
FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT
讓我詳細(xì)解釋每個(gè)階段:
1. FROM階段
首先確定數(shù)據(jù)來源,包括表連接操作。如果有JOIN,會(huì)先執(zhí)行笛卡爾積或根據(jù)JOIN條件進(jìn)行表連接。多個(gè)表的JOIN按從左到右的順序執(zhí)行。
2. WHERE階段
對(duì)FROM階段產(chǎn)生的結(jié)果集進(jìn)行條件過濾,篩選出符合條件的行。此時(shí)還不能使用SELECT中定義的別名,因?yàn)镾ELECT還沒執(zhí)行。
3. GROUP BY階段
按照指定的列對(duì)數(shù)據(jù)進(jìn)行分組,為聚合函數(shù)的計(jì)算做準(zhǔn)備。
4. HAVING階段
對(duì)分組后的結(jié)果進(jìn)行過濾,通常與聚合函數(shù)配合使用。HAVING可以使用SELECT中的別名(某些MySQL版本支持)。
5. SELECT階段
選擇要返回的列,執(zhí)行計(jì)算、函數(shù)調(diào)用等操作,生成最終的列。
6. DISTINCT階段
如果有DISTINCT關(guān)鍵字,對(duì)結(jié)果集去重。
7. ORDER BY階段
對(duì)結(jié)果集進(jìn)行排序??梢允褂肧ELECT中定義的別名。
8. LIMIT階段
限制返回的行數(shù),通常用于分頁。
常見場(chǎng)景示例
場(chǎng)景1:基礎(chǔ)查詢
SELECT name, age FROM users WHERE age > 18 ORDER BY age DESC LIMIT 10;
執(zhí)行順序:FROM users → WHERE age > 18 → SELECT name, age → ORDER BY age DESC → LIMIT 10
場(chǎng)景2:聚合查詢
SELECT department, COUNT(*) as emp_count, AVG(salary) as avg_salary FROM employees WHERE status = 'active' GROUP BY department HAVING COUNT(*) > 5 ORDER BY avg_salary DESC;
執(zhí)行順序:FROM employees → WHERE status = ‘active’ → GROUP BY department → HAVING COUNT() > 5 → SELECT department, COUNT(), AVG(salary) → ORDER BY avg_salary DESC
場(chǎng)景3:多表JOIN
SELECT u.name, o.order_date, o.amount FROM users u INNER JOIN orders o ON u.id = o.user_id WHERE o.order_date > '2025-01-01' ORDER BY o.order_date DESC;
執(zhí)行順序:FROM users u → INNER JOIN orders o → WHERE o.order_date > ‘2025-01-01’ → SELECT u.name, o.order_date, o.amount → ORDER BY o.order_date DESC
場(chǎng)景4:子查詢
SELECT name, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees) ORDER BY salary DESC;
執(zhí)行順序:先執(zhí)行子查詢得到平均工資 → FROM employees → WHERE salary > 子查詢結(jié)果 → SELECT name, salary → ORDER BY salary DESC
場(chǎng)景5:DISTINCT去重
SELECT DISTINCT city FROM customers WHERE country = 'China' ORDER BY city;
執(zhí)行順序:FROM customers → WHERE country = ‘China’ → SELECT city → DISTINCT → ORDER BY city
場(chǎng)景6:復(fù)雜的多表關(guān)聯(lián)與分組
SELECT d.name as dept_name, COUNT(e.id) as employee_count FROM departments d LEFT JOIN employees e ON d.id = e.department_id AND e.status = 'active' WHERE d.region = 'East' GROUP BY d.id, d.name HAVING employee_count > 0 ORDER BY employee_count DESC LIMIT 5;
執(zhí)行順序:FROM departments d → LEFT JOIN employees e (包含ON條件) → WHERE d.region = ‘East’ → GROUP BY d.id, d.name → HAVING employee_count > 0 → SELECT d.name, COUNT(e.id) → ORDER BY employee_count DESC → LIMIT 5
重要注意事項(xiàng)
WHERE vs HAVING的區(qū)別:WHERE在分組前過濾,不能使用聚合函數(shù);HAVING在分組后過濾,可以使用聚合函數(shù)。
別名的使用限制:WHERE子句中不能使用SELECT中定義的別名,因?yàn)閃HERE先于SELECT執(zhí)行。但ORDER BY和HAVING可以使用別名。
JOIN的ON條件:在FROM階段執(zhí)行,早于WHERE條件,因此在LEFT JOIN中,ON條件和WHERE條件的效果可能不同。
子查詢的執(zhí)行:相關(guān)子查詢可能會(huì)對(duì)外層查詢的每一行都執(zhí)行一次,非相關(guān)子查詢通常只執(zhí)行一次。
理解這個(gè)執(zhí)行順序?qū)帉懜咝QL、理解查詢結(jié)果以及優(yōu)化查詢性能都非常重要。
以上就是MySQL查詢SQL語句的執(zhí)行順序的方法的詳細(xì)內(nèi)容,更多關(guān)于MySQL查詢SQL語句執(zhí)行順序的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mysql分組排序取每組第一條的2種實(shí)現(xiàn)方式
開發(fā)中經(jīng)常會(huì)遇到,分組查詢最新數(shù)據(jù)的問題,下面這篇文章主要給大家介紹了關(guān)于Mysql分組排序取每組第一條的2種實(shí)現(xiàn)方式,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
MySQL 外鍵約束和表關(guān)系相關(guān)總結(jié)
一個(gè)項(xiàng)目中如果將所有的數(shù)據(jù)都存放在一張表中是不合理的,比如一個(gè)員工信息,公司只有2個(gè)部門,但是員工有1億人,就意味著員工信息這張表中的部門字段的值需要重復(fù)存儲(chǔ),極大的浪費(fèi)資源,因此可以定義一個(gè)部門表和員工信息表進(jìn)行關(guān)聯(lián),而關(guān)聯(lián)的方式就是外鍵。2021-06-06
MySQL如何快速批量插入1000w條數(shù)據(jù)
這篇文章主要給大家介紹了關(guān)于MySQL如何快速批量插入1000w條數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
mysql8.0.30用戶與權(quán)限管理的實(shí)踐
MySQL8.0新加了很多功能,其中在用戶管理中增加了角色的管理,本文主要介紹了mysql8.0.30用戶與權(quán)限管理的實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
MySQL幾點(diǎn)重要的性能指標(biāo)計(jì)算和優(yōu)化方法總結(jié)
下面小編就為大家?guī)硪黄狹ySQL幾點(diǎn)重要的性能指標(biāo)計(jì)算和優(yōu)化方法總結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
MySQL實(shí)現(xiàn)字段分割一行轉(zhuǎn)多行的示例代碼
這篇文章主要介紹了MySQL實(shí)現(xiàn)字段分割一行轉(zhuǎn)多行的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07

