你真的會玩SQL嗎?和平大使 內連接、外連接


大多數人一般寫多表查詢會這樣寫select * from tbA ,tbB  沒有用到JOIN關鍵字,太Low了,官網標准建議是用JOIN明確表間的關系,下面具體來講。
 
連接類型:
  1. 交叉聯接 得到所連接表的所有組合 (笛卡兒集)cross join
  2. 內聯接得到連接表的滿足條件的記錄組合inner join  on
  3. 外聯接(左、右)得到一個表的所有行,及其余表滿 足連接條件的行 full | left | right  outer join  on

     交叉聯接  

  在這類聯接的結果集內,兩個表中每兩個可能成對的行占一行。

    但是如果在交叉聯接中加入where 子句就相當與是內聯接

    例:

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

執行過程:

 

       內聯接  

僅顯示兩個聯接表中的匹配行的聯接。(這是查詢設計器中的默認聯接類型。)

例:

SELECT title, pub_name

       FROM titles INNER JOIN publishers

       ON titles.pub_id = publishers.pub_id

   執行過程:

 

     左向外聯接  

包括第一個命名表("左"表,出現在 JOIN 子句的最左邊)中的所有行。不包括右表中的不匹配行。

例:

SELECT titles.title_id,titles.title,publishers.pub_name

        FROM titles LEFT OUTER JOIN publishers

        ON titles.pub_id = publishers.pub_id

 

右向外聯接  

包括第二個命名表("右"表,出現在 JOIN 子句的最右邊)中的所有行。不包括左表中的不匹配行。

例:

SELECT titles.title_id, titles.title,publishers.pub_name

  FROM titles RIGHT OUTER JOIN publishers

        ON titles.pub_id = publishers.pub_id

 執行過程:

 

完整外部聯接  

包括所有聯接表中的所有行,不論它們是否匹配。

例:

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

/*返回值2007年2月12日下過訂單的客戶,以及他們的訂單。同時也返回在2007年2月12日沒有下過訂單的客戶。
涉及到表:Sales.Customers表和Sales.Orders表。
期望的輸出(按簡略格式顯示):
*/
custid      companyname     orderid     orderdate
----------- --------------- ----------- -----------------------
72          Customer AHPOP  NULL        NULL
58          Customer AHXHT  NULL        NULL
25          Customer AZJED  NULL        NULL
18          Customer BSVAR  NULL        NULL
91          Customer CCFIZ  NULL        NULL
...
33          Customer FVXPQ  NULL        NULL
53          Customer GCJSG  NULL        NULL
39          Customer GLLAG  NULL        NULL
16          Customer GYBBY  NULL        NULL
4           Customer HFBZG  NULL        NULL
5           Customer HGVLZ  10444       2007-02-12 00:00:00.000
42          Customer IAIJK  NULL        NULL
34          Customer IBVRG  NULL        NULL
63          Customer IRRVL  NULL        NULL
73          Customer JMIKW  NULL        NULL
15          Customer JUWXK  NULL        NULL
...
21          Customer KIDPX  NULL        NULL
30          Customer KSLQF  NULL        NULL
55          Customer KZQZT  NULL        NULL
71          Customer LCOUJ  NULL        NULL
77          Customer LCYBZ  NULL        NULL
66          Customer LHANT  10443       2007-02-12 00:00:00.000
38          Customer LJUCA  NULL        NULL
59          Customer LOLJO  NULL        NULL
36          Customer LVJSO  NULL        NULL
64          Customer LWGMD  NULL        NULL
29          Customer MDLWA  NULL        NULL
...

參考SQL:

--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',請注意這個結果又是什么呢?
View Code

 

/*返回沒有下過訂單的客戶。
涉及的表:Sales.Customers表和Sales.Orders表。
期望的輸出:
*/
custid      companyname
----------- ---------------
22          Customer DTDMN
57          Customer WVAXS

參考SQL:

--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
*/
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM