1 概述 1 概述 1.1 已發佈【SqlServer系列】文章 【SqlServer系列】SQLSERVER安裝教程 【SqlServer系列】資料庫三大範式 【SqlServer系列】表單查詢 1.2 本篇文章內容概要 1.3 本篇文章內容概括 在SQL語句中,關於表連接,若按照表的數量來劃分, ...
1 概述
1.1 已發佈【SqlServer系列】文章
1.2 本篇文章內容概要
1.3 本篇文章內容概括
在SQL語句中,關於表連接,若按照表的數量來劃分,可以劃分為單表連接、兩表連接和兩表以上連接,在本篇文章中,主要講解兩表連接,其他多表連接原理一樣。
關於表連接有很多種類,本文主要講解交叉連接,內連接,外連接(左外部連接,右外部連接,全連接),自連接。
1.4 本章測試樣表和Sql
業務場景:有兩張表,分為為顧客表Customers和顧客訂單表Orders,SQL語句分別如下:
創建Customes並初始化
1 --CREATE TABLE Customers 2 CREATE TABLE Customers 3 ( 4 CustID VARCHAR(50) NOT NULL, --顧客ID 5 CustName VARCHAR(50),--顧客姓名 6 CustCompany VARCHAR(50) --顧客公司 7 ) 8 9 --Initial Customers 10 11 INSERT INTO Customers VALUES('SXN-DD-01','趙武','A') 12 INSERT INTO Customers VALUES('SXN-DD-02','劉楊','B') 13 INSERT INTO Customers VALUES('SXN-DD-03','張永為','C') 14 INSERT INTO Customers VALUES('SXN-DD-04','李龍飛','D') 15 INSERT INTO Customers VALUES('SXN-FF-01','鄧華','E') 16 INSERT INTO Customers VALUES('SXN-HH-01','張濤明','F')
查詢結果為:
創建Order表並初始化
1 CREATE TABLE Orders 2 ( 3 CustID VARCHAR(50) NOT NULL, --顧客ID 4 OrdetID VARCHAR(50) --訂單ID 5 ) 6 7 --Initial Orders 8 9 INSERT INTO Orders VALUES('SXN-DD-01','SCCCCFFFFFSSOX002') 10 INSERT INTO Orders VALUES('SXN-DD-02','SCCCCFFFFFSSOX0X2') 11 INSERT INTO Orders VALUES('SXN-DD-03','') 12 INSERT INTO Orders VALUES('SXN-DD-04','') 13 INSERT INTO Orders VALUES('SXN-DD-05','SCCCCFFFFFSSOX0H2') 14 INSERT INTO Orders VALUES('SXN-DD-06','')
查詢結果為:
2 問題引入
Q1:寫一個查詢,生成從1到1000的整數序列。
3 交叉連接
3.1 SQL示例及示例結果
1 SELECT C.CustID,C.CustName,C.CustCompany,O.CustID,O.OrdetID 2 FROM Customers AS C 3 CROSS JOIN Orders AS O
結果:
3.2 示例結果分析
交叉連接使用關鍵字CROSS JOIN進行查詢,查詢的結果為笛卡兒積,從如上結果可以看出,查詢出的結果公有14行數據,因為Customers表和Orders表分別有4條記錄,4X4=16;
3.3 小結
a.在邏輯上,交叉連接是一種最簡單的聯接;
b.交叉連接只實現一個邏輯處理步驟———笛卡兒積;
c.操作:對輸入的兩個表進行操作,把它們連接起來,生成兩者的笛卡兒積,即將一個輸入表的每行與另一個表的所以行進行匹配,如果一個表有m行,而另一個表有n行,將得到m x n行的接果集;
d.結構:
SELECT tb1.tb1ConumName,tb2.tb2ConumName
FROM table1 AS tb1
CROSS JOIN table2 AS tb2
e.交叉連接使用的關鍵字:CROSS JOIN ;
f.交叉連接生成的接果集是一個虛擬表,虛擬表中的各列直接源於參與連接的兩個表;
4 內連接
4.1 SQL示例及示例結果
1 SELECT C.CustID,C.CustName,C.CustCompany,O.CustID,O.OrdetID 2 FROM Customers AS C 3 INNER JOIN Orders AS O 4 ON C.CustID=O.CustID
結果:
4.2 示例結果分析
內連接在交叉連接的基礎上外加過濾條件ON,如上例子中用Customers.CustID=Orders.CustID作為過濾條件,結果顯而易見。
4.3 小結
內聯接規則為笛卡爾積+用戶謂詞過濾:它首先像交叉連接一樣,對兩個輸入表進行笛卡爾積運算,然後根據用戶指定的謂詞對結果進行過濾;
5 外連接
5.1 SQL示例及示例結果(只分析左外部連接,因為右連接和全連接原理也是一樣的)
1 SELECT C.CustID,C.CustName,C.CustCompany,O.CustID,O.OrdetID 2 FROM Customers AS C 3 LEFT OUTER JOIN Orders AS O 4 ON C.CustID=O.CustID
結果:
5.2 示例結果分析
如上以Cutomers表作為左保留表,連接右表Orders列CustID缺少SXN-FF-01和SXN-HH-01,為了以左保留表為基準,用NULL占位符來填充。
5.3 小結
a.外連接:笛卡兒積+ON過濾+外部行;
b.在外連接中,要把一個表標記為“保留的”表,可以在表名之間使用關鍵字LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN,其中OUTER關鍵字是可選的。LEFT關鍵字表示左邊表的行是保留的,RIGHT關鍵字表示右邊表的行是保留的,而FULL關鍵字則表示左右兩邊表的行都是保留的;
c.外連接的第三個邏輯查詢處理步驟就是要識別保留表中按照ON條件在另一個表找不到與之匹配的那些行,再把這些行添加到連接的前兩個步驟生成的結果中。對於來自連接的非保留表的那些列,追加的外不行中的這些列則用NULL作為占位符;
d.從外連接保留表的角度來看,可以認為外連接結果中的數據行包括兩種內部行和外部行。內部行是指按照ON子句中的條件能在連接的另一邊找到匹配的那些行;而外部行則是指找不到匹配的那些行。內連接只返回內部行,外連接同時返回內部行和外部行;
e.使用外連接時,到底是在查詢的ON子句中,還是在WHERE子句中指定連結條件?從外連接保留表中的行來考慮該問題,ON子句中的過濾條件不是最終的,換句話說,ON子句中的條件並不能最終決定保留表中的部分行是否會在結果中出現,而只是判斷是否能夠匹配另一邊表中的某些行。所以,當需要表達一個非最終的條件時(即這個條件只決定哪些行可以匹配非保留表),就在ON子句中指定連接條件,當在生成外部行以後,要運用過濾器,而且希望過濾條件是最終的,就應該在WHERE子句中指定條件;
6 自連接
6.1 SQL示例及示例結果
1 SELECT C1.CustID AS C1CustID,C1.CustName AS C1CustName,C1.CustCompany AS C1CustCompany,C2.CustID,C2.CustName,C2.CustCompany 2 FROM Customers AS C1 3 JOIN Customers AS C2 4 ON C1.CustID=C2.CustID
結果:
6.2 示例結果分析
如上例子為自連接在內連接中的運用,在其他連接中的運用就不舉例子了,比較簡單。
6.3 小結
a.自連接為單個表取不同的別名,通過別名來連接;
b.自連接可以用於其它連接;
b.自連接可以看作交叉連接、內連接、外連接等連接的一個特例;
7 問題答案
Q1:KEY
CREATE TABLE Digits ( digit int not null primary key ) --Initial testing data for Digits INSERT INTO Digits VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9) --Query SELECT D3.digit*100+D2.digit*10+D1.digit+1 AS n FROM Digits AS D1 CROSS JOIN Digits AS D2 CROSS JOIN Digits AS D3 ORDER BY n
8 參考文獻
【01】Microsoft SqlServer 2008技術內幕:T-SQL 語言基礎
【02】Microsoft SqlServer 2008技術內幕:T-SQL 查詢
9 版權
- 感謝您的閱讀,若有不足之處,歡迎指教,共同學習、共同進步。
- 博主網址:http://www.cnblogs.com/wangjiming/。
- 極少部分文章利用讀書、參考、引用、抄襲、複製和粘貼等多種方式整合而成的,大部分為原創。
- 如您喜歡,麻煩推薦一下;如您有新想法,歡迎提出,郵箱:[email protected]。
- 可以轉載該博客,但必須著名博客來源。