日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL在执行JOIN ON时,到底发生了什么?

發(fā)布時間:2023/12/16 数据库 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL在执行JOIN ON时,到底发生了什么? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

點擊關注上方“SQL數(shù)據(jù)庫開發(fā)”,

設為“置頂或星標”,第一時間送達干貨

對于一些SQL初學者,寫一個簡單的單表查詢那是信手拈來。

(文末準備送幾本技術書籍給小伙伴們~)

但是遇到寫多表關聯(lián)查詢可能就懵逼了:為什么會有多表查詢這種“怪物”?要怎么寫?為什么要這樣為難我?這是誰發(fā)明的?

進而可能會引申出人生的終極哲學問題:我是誰?我在哪?我在做什么?

有點扯遠了,但確實能夠體會到一些初學者,對多表關聯(lián)查詢的困擾。今天我們就給大家講解多表關聯(lián)查詢到底是怎么一回事。

大家都知道,多表關聯(lián)查詢的關鍵字是JOIN...ON,如果只關心怎么使用,可以移步《SQL基礎知識V2——JOIN連接》。

本文主要講解JOIN ON在數(shù)據(jù)庫中是怎么執(zhí)行的。

測試環(huán)境

SQL Server 2017

測試樣表

我們新建兩張測試表Customers和Orders,表結(jié)構(gòu)如下:

表Customers

表Orders

要求:查詢每個客戶的訂單數(shù)量

我們先直接寫出查詢語句:

SELECT?a.CustomerName,Count(OrderID) Nums FROM?Customers a LEFT?JOIN?Orders b?ON?a.CustomerID=b.CustomerID GROUP?BY?a.CustomerName

結(jié)果如下:

問:這個結(jié)果是怎么來的呢?

要搞清楚這個結(jié)果是怎么來的,我們需要先知道一個概念:笛卡爾積

1、執(zhí)行笛卡爾積(交叉聯(lián)接)

什么是笛卡爾積?

笛卡爾乘積是指在數(shù)學中,兩個集合X和Y的笛卡爾積,表示為X×Y,第一個對象是X的成員而第二個對象是Y的所有可能有序?qū)Φ钠渲幸粋€成員。

具體如下圖:

而我們在進行SQL的表關聯(lián)時,JOIN的第一步就是生成笛卡爾積。我們上面的代碼

...?Customers?a?LEFT?JOIN??Orders?b?...

最開始是在數(shù)據(jù)庫中生成了一張笛卡爾積的虛表T1,T1里面的數(shù)量正是兩個表(Customers和Orders)數(shù)量的乘積9條(3 × 3),我們可以使用如下代碼獲得笛卡爾積:

SELECT? B.CustomerID, B.CustomerName, A.OrderID, A.CustomerID FROM?Orders A CROSS?JOIN?Customers B

查詢出來的數(shù)據(jù)如下:

虛表T1

2、執(zhí)行過濾篩選

當JOIN將兩個表生成笛卡爾積的虛表T1之后,隨后的ON開始執(zhí)行篩選功能,ON后面的條件就是指符合條件的返回結(jié)果TRUE,不符合條件的返回結(jié)果FALSE,以及未知情況UNKNOWN。

在繼續(xù)講解前我們需要先普及一下三值邏輯的概念

三值邏輯就是我們上面說到的ON返回的三個結(jié)果:TRUE,FALSE和UNKNOWN。

大多數(shù)的編程語言中返回的結(jié)果要么是TRUE,要么就是FALSE。而SQL中的UNKONWN通常與NULL值出現(xiàn)有關。

以下情況都會返回UNKNOWN:

NULL>21

NULL=NULL

X+NULL>Y

NULL代表一種缺失值,當把一個缺失值與其他任意值進行比較時,結(jié)果始終為UNKNOWN。

而我們上面的代碼中的ON的條件是這樣寫的:

...?a.CustomerID=b.CustomerID?...

意思就是取a(表Customers的別名)和b(表Orders的別名)中CustomerID相等的結(jié)果。根據(jù)這個篩選條件,虛表T1中可以生成相應邏輯值,如下圖:

ON篩選的邏輯結(jié)果表

從上面我們可以看到完全滿足條件(Logic Value的值為TRUE)的只有兩條記錄,數(shù)據(jù)庫會將這些結(jié)果插入到虛表T2,進行下一步的操作準備。

虛表T2

3、添加外部行

這一步只在外聯(lián)接(OUT JOIN)中才會發(fā)生。對于外聯(lián)接,通過為其指定一種聯(lián)接方式(LEFT,RIGHT或FULL),就把一個或兩個輸入表標記為保留表。

把表標記為保留表,即表示希望返回該表的所有行,即使ON過濾了一些行。

左連接(LEFT OUT JOIN)是把左邊的表作為保留表,右連接(RIGHT OUT JOIN)是把右邊的表作為保留表,全連接(FULL OUT JOIN)則是把兩個表都作為保留表。(我們在書寫時,通常會省略掉OUT)

在執(zhí)行完ON的篩選后,我們根據(jù)寫法來添加這些保留表中記錄。

我們上面的代碼使用的是LEFT JOIN,所以我們需要將左表(注:LEFT JOIN 左邊的表)Customers表作為保留表。

在ON篩選完后,我們發(fā)現(xiàn)Customers表中CustomerID為1的沒有在T2中,我們需要將這條記錄的相關信息添加到T2中生成虛表T3,并且將Order表中的所有數(shù)據(jù)置為NULL,因為他們(指表Orders中的兩列)不屬于保留表,不是我們需要保留的數(shù)據(jù)。這樣匯總后虛表T3中的數(shù)據(jù)如下:

虛表T3

這樣當我們再對表Orders中的OrderID計數(shù)時,CustomerID為1的客戶因為沒有訂單,返回的結(jié)果將為0,而CustomersID為2,3的客戶都有一個訂單,返回的結(jié)果將為1。

至此整個表關聯(lián)環(huán)節(jié)就執(zhí)行完成了。

參考文獻

《Microsoft SQL Server 2008技術內(nèi)幕:T-SQL查詢》

以上就是JOIN在數(shù)據(jù)庫中執(zhí)行的相關內(nèi)容,如有不明白的地方,歡迎在底下留言。

下面是福利環(huán)節(jié)~

薦書:《Oracle高性能系統(tǒng)架構(gòu)實戰(zhàn)大全》編輯推薦: (1) 深入淺出:詳解與 Oracle 數(shù)據(jù)庫性能相關的方方面面,涵蓋 Oracle 的體系架構(gòu)及其背后的運行機制。? (2)直擊難點:全面解析Oracle SQL 執(zhí)行計劃和Oracle SQL 性能分析與優(yōu)化。? (3)全新實戰(zhàn):真實有效的實戰(zhàn)案例再現(xiàn)Oracle數(shù)據(jù)庫開發(fā)過程中的問題及解決思路。? (4)雙管齊下:先設定方案,然后從應用角度和數(shù)據(jù)庫角度綜合考慮,逐一分析實現(xiàn)環(huán)境。如何購買: 點擊閱讀原文購買,也可點擊下方小程序購買~ 如何贈送: 1、必須是關注了本公眾號的小伙伴 2、留言集贊數(shù)大于30贊且排名前五的小伙伴,每人贈送一本,定價128RMB。 3、截止2020年7月10日上午9:00——End—— 后臺回復關鍵字:1024,獲取一份精心整理的技術干貨 后臺回復關鍵字:進群,帶你進入高手如云的交流群。 推薦閱讀 SQL 語法速成手冊可怕,如果張東升是個程序員…… 我只會SQL,到底能不能找到好工作呢? Oracle常用函數(shù)整理MySQL常用函數(shù)整理這是一個能學到技術的公眾號,歡迎關注

總結(jié)

以上是生活随笔為你收集整理的SQL在执行JOIN ON时,到底发生了什么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。