
你真的會玩SQL嗎?之邏輯查詢處理階段
最近要對數(shù)據(jù)庫進(jìn)行優(yōu)化,但由于工作項(xiàng)目中已經(jīng)很少親自寫SQL而且用的都不是很復(fù)雜的語句,所以有些生疏了,于是翻翻N年前的筆記資料,想以此來記錄回顧總結(jié)一些實(shí)用的SQL干貨讓大家來學(xué)習(xí),若有不對之處可提出。
記得剛出來行走江湖的時候也是只會增、刪、改、查四大法寶,一般公司沒有多少復(fù)雜的業(yè)務(wù),所以就夠用了。但后來看著大神會寫個幾百行的SQL存儲過程就感覺自己是不是弱爆了。
如今是大數(shù)據(jù)的時代,對數(shù)據(jù)的處理要求越來越重視,要出各種數(shù)據(jù)報表,因此百萬數(shù)據(jù)處理速度,數(shù)據(jù)庫明顯比后臺邏輯處理的優(yōu)勢不是一個別。
下面進(jìn)入正題,寫了多年的SQL,你真的玩會了SQL嗎?
在此我想再次提示一個數(shù)據(jù)處理的中心思想,SQL數(shù)據(jù)處理是集合思維,不要用邏輯思維來思考。
文中的示例來自自己的積累和TSQL2008技術(shù)內(nèi)幕。
基礎(chǔ)知識普及
對于教條式的定義請自己去查,此處不會涉及到文鄒鄒的知識,但還是強(qiáng)調(diào)一下基礎(chǔ)的重要性,即使你理解了所有的概念,但當(dāng)組合起來用時也會一頭霧水。
邏輯查詢處理階段
在以上的10個處理步驟中, 每一步的處理都生成一個虛擬表來作為下一步的輸入. 虛擬表對于調(diào)用者或輸出查詢來說是不存在的, 僅在最后步驟生成的表才會返回給調(diào)用者或者輸出查詢. 如果某一子句沒有出現(xiàn)在SQL語句中, 這一步就被簡單跳過..
這10個具體步驟是:
1.FROM: from子句中的兩個表首先進(jìn)行交叉連接(笛卡爾積), 生成虛擬表VT1。
2.ON:
on條件作用在VT1上, 將條件為True的行生成VT2。
3.OUTER: 如果outer join被指定, 則根據(jù)外連接條件,
將左表or右表or多表的未出現(xiàn)在VT2查詢結(jié)果中的行加入到VT2后生成VT3。
4.WHERE: VT3表中應(yīng)用Where條件,
結(jié)果為真的行用來生成VT4。
5.GROUP BY: 根據(jù)Group by指定的列, 將VT4的行組織到不同的組中,
生成VT5。
6.CLUB|ROLLUP: 超級組(分組之后的分組)被添加到VT5中, 生成VT6。
7.HAVING: Having用來篩選組,
VT6上符合條件的組將用來生成VT7。
8.SELECT: select子句用來選擇指定的列, 并生成VT8。
9.DISTINCT:
從VT8中刪除重復(fù)的行后, VT9被生成。
10.ORDER BY: 根據(jù)Order by子句, VT9中的行被排序, 生成游標(biāo)10。
注意事項(xiàng):
第一步中FROM: 需要對兩表同時存在的列添加前綴, 以免混淆.
第二步中ON: 在SQL特有的三值邏輯(true,false,unknown)中, unkown的值也是確定的, 只是在不同情況下有時為true, 有時為false. 一個總的原則是: unknown的值非真即假, 非假即真. 也就是時說, unknown只能取true和false里面的一個值, 但是unknown的相反還是unknown.如:
在ON、WHERE和HAVING中做過濾條件時, unknown看做false;
在CHECK約束中, unknown被看做是true;
在條件中, 兩個NULL的比較結(jié)果還是Unknown.
在UNIQUE和PRIMARY KEY約束、排序和分組中, NULL被看做是相等的. 例如Group by 將null分為一組, 而order by將所有null排在一起.
第三步中OUTER: 如果多余兩張表, 則將VT3和FROM中的下一張表再次執(zhí)行從第一步到第三步的過程.
第四步中WHERE: 由于此刻沒有分組, 也沒有執(zhí)行select所以, where子句中不能寫分組函數(shù), 也不能使用表的別名. 并且, 只有在外連接時, on和where的邏輯才是不同的, 因此建議連接條件放在on中.
第五步中GROUP BY: 如果查詢中包含Group by 子句, 那么所有的后續(xù)操作(having, select等)都是對每一組的結(jié)果進(jìn)行操作.
Group by子句中可以使用組函數(shù), 在Sql 2000中一旦使用組函數(shù), 其后面的步驟將都不能處理, 而在
Sql2005中沒有這個限制.
第六步不常用, 略過.
第七步中HAVING: having表達(dá)式是僅有的分組條件. 注意: count(*)不會忽略掉null, 而count(field)會; 此外分組函數(shù)中不支持子查詢做輸入.
第八步中SELECT: 如果包含Group By子句, 那么在第5步后將只能使用Group By子句中出現(xiàn)的列, 如果要使用其他原始列則, 只能使用組函數(shù).
另外, select在第八步才執(zhí)行, 因此別名只能第八步之后才能使用, 并且只能在order by中使用.
第九步中DISTINCT: 當(dāng)使用Group By子句時, 使用Distinct是多余的, 他不會刪除任何記錄.
第十步中ORDER BY: 按Order by子句指定的列排序后, 返回游標(biāo)VC10.
別名只能在Order by子句中使用.
如果定義了Distinct子句, 則只能排序上一步中返回的表VT9, 如果沒有指定Distinct子句, 則可以排序不再最終結(jié)果集中的列. 例如: 如果不加Distinct則Order by可以訪問VT7和VT8中的內(nèi)容.
這一步最不同的是它返回的是游標(biāo)而不是表, Sql是基于集合論的, 集合中的元素師沒有順序的, 一個在表上引用Order by排序的查詢返回一個按照特定特定物理順序組織的對象—游標(biāo). 所以對于視圖、子查詢、派生表等均不能將order by結(jié)果作為其數(shù)據(jù)來源.
建議: 使用表的表達(dá)式時, 不允許使用order by子句的查詢, 因此除非你真的要對行排序, 否則不要使用order by 子句.
內(nèi)容為 RJ 寫的,邏輯非常清楚,值得花點(diǎn)時間理解,再次強(qiáng)調(diào)是因?yàn)閺?fù)雜的集合數(shù)據(jù)處理過程中會得到不是你想要的結(jié)果,這時就要你自己腦袋當(dāng)SQL處理器來推出結(jié)果查出問題,可能大多數(shù)寫了幾年的SQL都還沒弄明白,但到了用時還是提前理解下,非常重要。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點(diǎn)數(shù)據(jù)時的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實(shí)踐到業(yè)務(wù)價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10