- 一條查詢sql語句的執(zhí)行流程:
- FROM <表名>
選取表跌榔,將<left_table>及<right_table>表數(shù)據(jù)通過笛卡爾積生成虛表VT1(此時(shí)VT1包括表中所有的字段?)绪囱, - ON <篩選條件>
對笛卡爾積的虛表VT1根據(jù)條件進(jìn)行篩選VT2 - JOIN <join, left join, right join...> <join表>
指定join,保留表中未匹配的行就會作為外部行添加到虛擬表VT2中像屋,產(chǎn)生虛表VT3。例如left join會將左表的剩余數(shù)據(jù)添加到虛表VT2中边篮,生成虛表VT3 - WHERE <where條件>
對上述虛表VT3進(jìn)行篩選, 將符合<where-condition>的記錄才會被插入到虛表VT4
此時(shí)還沒有進(jìn)行g(shù)roup by己莺,因此WHERE中出現(xiàn)對統(tǒng)計(jì)的過濾是不對的(不可以使用聚合函數(shù)),若需要?jiǎng)t在having中實(shí)現(xiàn)戈轿。
請思考一下凌受,對于同樣的篩選條件:在on和where 處進(jìn)行篩選有結(jié)果會有不同? - GROUP BY <分組條件>
分組, 根據(jù)分組條件思杯,對VT4進(jìn)行分組操作胜蛉,生成虛表VT5(若是有g(shù)roup by,那么后面的所有步驟都只能得到的VT4的列及聚合函數(shù)(count色乾、sum誊册、avg等),即VT5虛表只會生成這些)
注意:所有select的字段暖璧,除聚合函數(shù)中的字段外案怯,都必須在group by中出現(xiàn) - HAVING <分組篩選>
對分組后的結(jié)果進(jìn)行篩選,即對虛表VT5進(jìn)行篩選生成VT6 - SELECT<返回?cái)?shù)據(jù)列表>
選擇指定的列澎办,生成虛擬表VT7(再次提醒:若有g(shù)roup by子句中嘲碱,則此處除了group by子句中的列+聚合函數(shù)除外,不能再出現(xiàn)其它的列浮驳。請思考下悍汛,為什么不建議Select *from?) - DISTINCT
數(shù)據(jù)除重,生成VT8 - ORDER BY<排序條件>
將虛表VT8按照<order_by_list>進(jìn)行排序操作,產(chǎn)生虛擬表VT9,請注意:這是唯一的一個(gè)可以使用select列表中別名的步驟 - LIMIT <行數(shù)限制>
取出指定行的記錄至会,產(chǎn)生虛擬表VT10, 并將結(jié)果返回
- 擴(kuò)展:帶有子查詢的執(zhí)行順序(堅(jiān)持小表驅(qū)動大表的原則)
1. 不相關(guān)子查詢:子查詢的查詢條件不依賴于父查詢(由里向外 逐層處理离咐。即每個(gè)子查詢在上一級查詢處理之前求解,子查詢的結(jié)果用于建立其父查詢的查找條件)
select * from emp where sal = (select max(sal) from emp);
先執(zhí)行內(nèi)層查詢奉件,作為where 條件再執(zhí)行外層查詢
2. 相關(guān)子查詢:子查詢的查詢條件依賴于父查詢(先取外層查詢中表的第一個(gè)元組宵蛀,根據(jù)它與內(nèi)層查詢相關(guān)的屬性值處理內(nèi)層查詢,若WHERE子句返回值為真县貌,則取此元組放入結(jié)果表术陶,
然后再取外層表的下一個(gè)元組,重復(fù)這一過程煤痕,直至外層表全部檢查完為止)
select * from dept d where exists(select * from emp e where e.deptno = d.deptno);
先執(zhí)行外層查詢梧宫,再執(zhí)行內(nèi)層查詢