日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

T-SQL是ANSI和ISO SQL標(biāo)準(zhǔn)的MS SQL擴(kuò)展,其正式名稱為Transact-SQL,但一般程序員都稱其為T-SQL。本文是我學(xué)習(xí)《T-SQL查詢》一書的讀書筆記,為你講解邏輯查詢的內(nèi)幕。

1 邏輯查詢處理的各個階段

流程總覽

T-SQL | 邏輯查詢處理內(nèi)幕

 

階段解釋

(1)FROM:標(biāo)識出查詢的來源表,處理表運算符。每個運算符會應(yīng)用一系列的子階段。eg.在JOIN連接運算中涉及的階段是笛卡爾積、ON篩選器和添加外部行。FROM階段會生成一個虛擬表,這里暫定為VT1。

    • (1-J1)笛卡爾積:對涉及到的兩個表執(zhí)行笛卡爾積(交叉聯(lián)接),生成虛擬表VT1-J1。
    • (1-J2)ON篩選器:對VT1-J1中的行根據(jù)ON子句中出現(xiàn)的謂詞進(jìn)行篩選。只有讓該謂詞取值為TRUE的行,才能插入到VT1-J2中。
    • (1-J3)添加外部行:如果指定了OUTER JOIN(相對于CROSS JOIN或INNER JOIN),則將保留表(Preserved Table)中沒有找到匹配的行,作為外部行添加到VT1-J2中,生成VT1-J3。

(2)WHERE:根據(jù)在WHERE子句中出現(xiàn)的謂詞對VT1中的行進(jìn)行篩選。只有讓謂詞計算結(jié)果為TRUE的行,才會插入VT2中。

(3)GROUP BY:按照GROUP BY子句中指定的列名列表,將VT2中的行進(jìn)行分組,生成VT3。最終,每個分組只有一個結(jié)果行。

(4)HAVING:根據(jù)HAVING子句出現(xiàn)的謂詞對VT3中的分組進(jìn)行篩選。只有讓謂詞計算結(jié)果為TRUE的行,才會插入VT4。

(5)SELECT:處理SELECT子句中的元素,產(chǎn)生VT5。

    • (5-1)計算表達(dá)式:計算SELECT列表中的表達(dá)式,生成VT5-1。
    • (5-2)DISTINCT:刪除VT5-1中的重復(fù)行,生成VT5-2。
    • (5-3)TOP:根據(jù)ORDER BY子句定義的邏輯排序,從VT5-2中選擇前面指定數(shù)量或百分比的行,生成VT5-3。

(6)ORDER BY:根據(jù)ORDER BY子句中指定的列名列表,對VT5-3中的行進(jìn)行排序,生成游標(biāo)VC6。

2 一個邏輯查詢的示例

示例場景

假設(shè)有兩張表:Customers和Orders,表結(jié)構(gòu)和數(shù)據(jù)如下:  

T-SQL | 邏輯查詢處理內(nèi)幕

 

這里我們要查詢來自Madrid并且訂單數(shù)少于3個的客戶,查詢代碼和結(jié)果也如下圖所示:

T-SQL | 邏輯查詢處理內(nèi)幕

 

階段詳解

(1)FROM階段:

FROM dbo.Customers AS C  LEFT OUTER JOIN dbo.Orders AS O    ON C.customerid = O.customerid

步驟1-J1=>笛卡爾積

這里先不考慮LEFT OUTER,通過JOIN交叉聯(lián)接后形成虛擬表VT1-J1:

T-SQL | 邏輯查詢處理內(nèi)幕

 

步驟1-J2=>ON篩選器

ON篩選器的作用在于從上一步生成的虛擬表VT1-J1中的所有行中篩選出只有使 C.customerid = O.customerid 為TRUE的那些行,將其輸出到新的虛擬表VT1-J2中。

T-SQL | 邏輯查詢處理內(nèi)幕

 

步驟1-J3=>添加外部行

這一步只會在外鏈接(OUTER JOIN)中才會發(fā)生。這里是:Customers AS C LEFT OUTER JOIN Orders AS O,即Customer作為保留表。最終的虛擬表VT1-J3如下:

T-SQL | 邏輯查詢處理內(nèi)幕

 

*.這里Customer作為保留表,所以FISSA雖然沒有滿足ON篩選器,但是也會被添加到虛擬表中。

(2)WHERE階段

WHERE C.city = 'Madrid'

在此階段會去掉VT1中客戶為MRPHS的行(因為其cityid不是Madrid),生成如下所示的VT2:

T-SQL | 邏輯查詢處理內(nèi)幕

 

ON和WHERE的區(qū)別:WHERE對行的刪除是最終的,而ON對行的刪除并不是,因此步驟1-J3添加外部行時會再添加回來。此外,只有當(dāng)使用外連接時,ON和WHERE才存在這種邏輯區(qū)別。

(3)GROUP BY階段:

GROUP BY C.customerid

這一步將VT2中的數(shù)據(jù)行按組進(jìn)行重組,得到VT3如下圖所示:

T-SQL | 邏輯查詢處理內(nèi)幕

 

(4)HAVING階段:

HAVING COUNT(O.orderid) < 3

這一步從VT3中進(jìn)行篩選,只有使得COUNT(O.orderid)<3邏輯值為TRUE的組,才會進(jìn)入到VT4。HAVING篩選器是唯一可用于分組數(shù)據(jù)的篩選器。

T-SQL | 邏輯查詢處理內(nèi)幕

 

這里沒有使用COUNT(*)是因為在外聯(lián)接中,COUNT(*)會把外部行也統(tǒng)計在內(nèi),比如會將FISSA的訂單數(shù)統(tǒng)計為1,這明顯是錯誤的。

(5)SELECT階段

步驟5-1=>計算表達(dá)式

SELECT C.customerid, COUNT(O.orderid) as numorders

得到VT5-1

T-SQL | 邏輯查詢處理內(nèi)幕

 

步驟5-2=>應(yīng)用DISTINCT子句

此示例木有DISTINCT子句,故VT5-1沒有變化。

步驟5-3=>應(yīng)用TOP選項

TOP選項時T-SQL特有的一項功能,允許指定要返回的行數(shù)或百分比。不過,此示例也沒有指定TOP,估計VT5=VT5-1。

(6)ORDER BY階段:

ORDER BY numorders

這一步將對VT5進(jìn)行排序,返回游標(biāo)VC6。ORDER BY子句也是唯一可以重用SELECT列表中創(chuàng)建的列別名的步驟。

T-SQL | 邏輯查詢處理內(nèi)幕

 

參考資料

[美] Itzik Ben-Gan 著,《SQL Server 2008技術(shù)內(nèi)幕:T-SQL查詢》

分享到:
標(biāo)簽:邏輯 查詢
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定