大多數人一般寫多表查詢會這樣寫select * from tbA ,tbB 沒有用到JOIN關鍵字,太Low了,官網標準建議是用JOIN明確表間的關係,下面具體來講。
連線型別:
- 交叉聯接 得到所連線表的所有組合 (笛卡兒集)cross join
- 內聯接得到連線表的滿足條件的記錄組合inner join on
- 外聯接(左、右)得到一個表的所有行,及其餘表滿 足連線條件的行 full | left | right outer join on
交叉聯接
在這類聯接的結果集內,兩個表中每兩個可能成對的行佔一行。
但是如果在交叉聯接中加入where 子句就相當與是內聯接
例:
1 2 3 4 5 |
SELECT title, pub_name FROM titles Cross JOIN publishers Where titles.pub_id = publishers.pub_id |
這就相當於我們一最開始的寫法:SELECT title, pub_name FROM titles , publishers Where titles.pub_id = publishers.pub_id
執行過程:
內聯接
僅顯示兩個聯接表中的匹配行的聯接。(這是查詢設計器中的預設聯接型別。)
例:
1 2 3 4 5 |
SELECT title, pub_name FROM titles INNER JOIN publishers ON titles.pub_id = publishers.pub_id |
執行過程:
左向外聯接
包括第一個命名錶(”左”表,出現在 JOIN 子句的最左邊)中的所有行。不包括右表中的不匹配行。
例:
1 2 3 4 5 |
SELECT titles.title_id,titles.title,publishers.pub_name FROM titles LEFT OUTER JOIN publishers ON titles.pub_id = publishers.pub_id |
右向外聯接
包括第二個命名錶(”右”表,出現在 JOIN 子句的最右邊)中的所有行。不包括左表中的不匹配行。
例:
1 2 3 4 5 |
SELECT titles.title_id, titles.title,publishers.pub_name FROM titles RIGHT OUTER JOIN publishers ON titles.pub_id = publishers.pub_id |
執行過程:
完整外部聯接
包括所有聯接表中的所有行,不論它們是否匹配。
例:
1 2 3 4 5 |
SELECT titles.title_id, titles.title, publishers.pub_name FROM titles FULL OUTER JOIN publishers ON titles.pub_id = publishers.pub_id |
練習:
此後用到的用例資料庫是SQL2008裡面的
用例資料庫檔案:連結:http://pan.baidu.com/s/1qW1QxA0 密碼:dqxx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/*返回值2007年2月12日下過訂單的客戶,以及他們的訂單。同時也返回在2007年2月12日沒有下過訂單的客戶。 涉及到表:Sales.Customers表和Sales.Orders表。 期望的輸出(按簡略格式顯示): */ custid companyname orderid orderdate ----------- --------------- ----------- ----------------------- Customer AHPOP NULL NULL Customer AHXHT NULL NULL Customer AZJED NULL NULL Customer BSVAR NULL NULL Customer CCFIZ NULL NULL ... Customer FVXPQ NULL NULL Customer GCJSG NULL NULL Customer GLLAG NULL NULL Customer GYBBY NULL NULL Customer HFBZG NULL NULL Customer HGVLZ 10444 2007-02-12 00:00:00.000 Customer IAIJK NULL NULL Customer IBVRG NULL NULL Customer IRRVL NULL NULL Customer JMIKW NULL NULL Customer JUWXK NULL NULL ... Customer KIDPX NULL NULL Customer KSLQF NULL NULL Customer KZQZT NULL NULL Customer LCOUJ NULL NULL Customer LCYBZ NULL NULL Customer LHANT 10443 2007-02-12 00:00:00.000 Customer LJUCA NULL NULL Customer LOLJO NULL NULL Customer LVJSO NULL NULL Customer LWGMD NULL NULL Customer MDLWA NULL NULL ... |
參考SQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
--answer: select c.custid,c.companyname,o.orderid,o.orderdate from Sales.Customers as c left join Sales.Orders as o on c.custid=o.custid and o.orderdate='2007-2-12' /* 1.將表Sales.Customers別名為c和表Sales.Orders別名為o應用ON篩選器以custid和o.orderdate='2007-2-12'為條件左外連線,生成虛擬表VT1, 2.新增外部行,外部行中非保留表中的屬性被賦值為NULL,生成虛擬表VT2 3.處理select列表,從虛擬表VT2中查詢出c.custid,c.companyname,o.orderid,o.orderdate生成虛擬表VT3 */ 注意 and o.orderdate='2007-2-12' 改成 where o.orderdate='2007-2-12',請注意這個結果又是什麼呢? |
1 2 3 4 5 6 7 8 |
/*返回沒有下過訂單的客戶。 涉及的表:Sales.Customers表和Sales.Orders表。 期望的輸出: */ custid companyname ----------- --------------- Customer DTDMN Customer WVAXS |
參考SQL:
1 2 3 4 5 6 7 8 9 10 11 12 |
--answer: select c.custid,c.companyname from Sales.Customers as c left join Sales.Orders as o on c.custid=o.custid where o.orderid is null /* 1.將表Sales.Customers別名為c和表Sales.Orders別名為o應用ON篩選器以custid為條件左外連線,生成虛擬表VT1, 2.新增外部行,外部行中非保留表中的屬性被賦值為NULL,生成虛擬表VT2 3.應用where篩選器選出o.orderid 為 null的資料生成虛擬表VT3 4.處理select列表,查詢出c.custid,c.companyname生成虛擬表VT4 */ |