1.概述
1、内聯接(典型的聯接運算,使用像 = 或 <> 之類的比較運算符)。包括相等聯接和自然聯接。
内聯接使用比較運算符根據每個表共有的列的值比對兩個表中的行。例如,檢索 students和courses表中學生辨別号相同的所有行。
2、外聯接。外聯接可以是左向外聯接、右向外聯接或完整外部聯接。
在 FROM子句中指定外聯接時,可以由下列幾組關鍵字中的一組指定:
1)LEFT JOIN或LEFT OUTER JOIN
左向外聯接的結果集包括 LEFT OUTER子句中指定的左表的所有行,而不僅僅是聯接列所比對的行。如果左表的某行在右表中沒有比對行,則在相關聯的結果集行中右表的所有選擇清單列均為空值。
2)RIGHT JOIN 或 RIGHT OUTER JOIN
右向外聯接是左向外聯接的反向聯接。将傳回右表的所有行。如果右表的某行在左表中沒有比對行,則将為左表傳回空值。
3)FULL JOIN 或 FULL OUTER JOIN
完整外部聯接傳回左表和右表中的所有行。當某行在另一個表中沒有比對行時,則另一個表的選擇清單列包含空值。如果表之間有比對行,則整個結果集行包含基表的資料值。
例子:
-------------------------------------------------
a表 id name b表 id job parent_id
1 張3 1 23 1
2 李四 2 34 2
3 王武 3 34 4
a.id同parent_id 存在關系
--------------------------------------------------
1) 内連接配接
select a.*,b.* from a inner join b on a.id=b.parent_id
結果是
1 張3 1 23 1
2 李四 2 34 2
2)左連接配接
select a.*,b.* from a left join b on a.id=b.parent_id
結果是
1 張3 1 23 1
2 李四 2 34 2
3 王武 null
3) 右連接配接
select a.*,b.* from a right join b on a.id=b.parent_id
結果是
1 張3 1 23 1
2 李四 2 34 2
null 3 34 4
4) 完全連接配接 (不做過多概述)
select a.*,b.* from a full join b on a.id=b.parent_id
結果是
1 張3 1 23 1
2 李四 2 34 2
null 3 34 4
3 王武 null
2.内連接配接(INNER JOIN)
内連接配接(INNER JOIN):有兩種,顯式的和隐式的,傳回連接配接表中符合連接配接條件和查詢條件的資料行。(所謂的連結表就是資料庫在做查詢形成的中間表)。
例如:下面的語句3和語句4的結果是相同的。
語句1:隐式的内連接配接,沒有INNER JOIN,形成的中間表為兩個表的笛卡爾積。
SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME
FROM CUSTOMERS C,ORDERS O
WHERE C.ID=O.CUSTOMER_ID;
語句2:顯示的内連接配接,一般稱為内連接配接,有INNER JOIN,形成的中間表為兩個表經過ON條件過濾後的笛卡爾積。
SELECT O.ID,O.ORDER_NUMBER,C.ID,C.NAME
FROM CUSTOMERS C INNER JOIN ORDERS O ON C.ID=O.CUSTOMER_ID;
3.外連接配接(OUTER JOIN):
外連不但傳回符合連接配接和查詢條件的資料行,還傳回不符合條件的一些行。外連接配接分三類:左外連接配接(LEFT OUTER JOIN)、右外連接配接(RIGHT OUTER JOIN)和全外連接配接(FULL OUTER JOIN)。
三者的共同點是都傳回符合連接配接條件和查詢條件(即:内連接配接)的資料行。不同點如下:
左外連接配接還傳回左表中不符合連接配接條件單符合查詢條件的資料行。
右外連接配接還傳回右表中不符合連接配接條件單符合查詢條件的資料行。
全外連接配接還傳回左表中不符合連接配接條件單符合查詢條件的資料行,并且還傳回右表中不符合連接配接條件單符合查詢條件的資料行。全外連接配接實際是上左外連接配接和右外連接配接的數學合集(去掉重複),即“全外=左外 UNION 右外”。
說明:左表就是在“(LEFT OUTER JOIN)”關鍵字左邊的表。右表當然就是右邊的了。在三種類型的外連接配接中,OUTER 關鍵字是可省略的。
下面舉例說明:
語句3:左外連接配接(LEFT OUTER JOIN)
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
語句4:右外連接配接(RIGHT OUTER JOIN)
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O RIGHT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
注意:WHERE條件放在ON後面查詢的結果是不一樣的。例如:
語句5:WHERE條件獨立。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
WHERE O.ORDER_NUMBER<>'MIKE_ORDER001';
語句6:将語句5中的WHERE條件放到ON後面。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID AND O.ORDER_NUMBER<>'MIKE_ORDER001';
從語句5和語句6查詢的結果來看,顯然是不相同的,語句6顯示的結果是難以了解的。是以,推薦在寫連接配接查詢的時候,ON後面隻跟連接配接條件,而對中間表限制的條件都寫到WHERE子句中。
語句7:全外連接配接(FULL OUTER JOIN)。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O FULL OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
注意:MySQL是不支援全外的連接配接的,這裡給出的寫法适合Oracle和DB2。但是可以通過左外和右外求合集來擷取全外連接配接的查詢結果。
語句8:左外和右外的合集,實際上查詢結果和語句7是相同的。
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O LEFT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID
UNION
SELECT O.ID,O.ORDER_NUMBER,O.CUSTOMER_ID,C.ID,C.NAME
FROM ORDERS O RIGHT OUTER JOIN CUSTOMERS C ON C.ID=O.CUSTOMER_ID;
4.SQL查詢的基本原理:兩種情況介紹。
第一、單表查詢:根據WHERE條件過濾表中的記錄,形成中間表(這個中間表對使用者是不可見的);然後根據SELECT的選擇列選擇相應的列進行傳回最終結果。
第二、兩表連接配接查詢:對兩表求積(笛卡爾積)并用ON條件和連接配接連接配接類型進行過濾形成中間表;然後根據WHERE條件過濾中間表的記錄,并根據SELECT指定的列傳回查詢結果。
第三、多表連接配接查詢:先對第一個和第二個表按照兩表連接配接做查詢,然後用查詢結果和第三個表做連接配接查詢,以此類推,直到所有的表都連接配接上為止,最終形成一個中間的結果表,然後根據WHERE條件過濾中間表的記錄,并根據SELECT指定的列傳回查詢結果。
了解SQL查詢的過程是進行SQL優化的理論依據。
ON後面的條件(ON條件)和WHERE條件的差別:
ON條件:是過濾兩個連結表笛卡爾積形成中間表的限制條件。
WHERE條件:在有ON條件的SELECT語句中是過濾中間表的限制條件。在沒有ON的單表查詢中,是限制實體表或者中間查詢結果傳回記錄的限制。在兩表或多表連接配接中是限制連接配接形成最終中間表的傳回結果的限制。
從這裡可以看出,将WHERE條件移入ON後面是不恰當的。推薦的做法是:
ON隻進行連接配接操作,WHERE隻過濾中間表的記錄。
總結
連接配接查詢是SQL查詢的核心,連接配接查詢的連接配接類型選擇依據實際需求。如果選擇不當,非但不能提高查詢效率,反而會帶來一些邏輯錯誤或者性能低下。下面總結一下兩表連接配接查詢選擇方式的依據:
1、 查兩表關聯列相等的資料用内連接配接。
2、 Col_L是Col_R的子集時用右外連接配接。
3、 Col_R是Col_L的子集時用左外連接配接。
4、 Col_R和Col_L彼此有交集但彼此互不為子集時候用全外。
多個表查詢的時候,這些不同的連接配接類型可以寫到一塊。例如:
SELECT T1.C1,T2.CX,T3.CY
FROM TAB1 T1
INNER JOIN TAB2 T2 ON (T1.C1=T2.C2)
INNER JOIN TAB3 T3 ON (T1.C1=T2.C3)
LEFT OUTER JOIN TAB4 ON(T2.C2=T3.C3);
WHERE T1.X >T3.Y;
上面這個SQL查詢是多表連接配接的一個示範。
5.操作符下的左右連接配接
對于外連接配接, 也可以使用“(+) ”來表示。 關于使用(+)的一些注意事項:
1.(+)操作符隻能出現在where子句中,并且不能與outer join文法同時使用。
2. 當使用(+)操作符執行外連接配接時,如果在where子句中包含有多個條件,則必須在所有條件中都包含(+)操作符
3.(+)操作符隻适用于列,而不能用在表達式上。
4.(+)操作符不能與or和in操作符一起使用。
5.(+)操作符隻能用于實作左外連接配接和右外連接配接
左連接配接
用(+)來實作, 這個+号可以這樣來了解:+ 表示補充,即哪個表有加号,這個表就是比對表。是以加号寫在右表,左表就是全部顯示,故是左連接配接。
SQL> Select * from dave a,bl b where a.id=b.id(+); -- 注意: 用(+) 就要用關鍵字where
右連接配接
用(+)來實作, 這個+号可以這樣來了解:+ 表示補充,即哪個表有加号,這個表就是比對表。是以加号寫在左表,右表就是全部顯示,故是右連接配接。
SQL> Select * from dave a,bl b where a.id(+)=b.id;
6.On與where的差別
資料庫在通過連接配接兩張或多張表來傳回記錄時,都會生成一張中間的臨時表,然後再将這張臨時表傳回給使用者。
在使用left jion時,on和where條件的差別如下:
1、on條件是在生成臨時表時使用的條件,它不管on中的條件是否為真,都會傳回左邊表中的記錄。
2、where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有left join的含義(必須傳回左邊表的記錄)了,條件不為真的就全部過濾掉。
假設有兩張表:
表1:tab2 id size
1 10
2 20
3 30
表2:tab2 size name
10 AAA
20 BBB
20 CCC
兩條SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form tab1 left join tab2 on (tab1.size = tab2.sizeand tab2.name=’AAA’)
第一條SQL的過程:
1、中間表
on條件:
tab1.size = tab2.size tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 20 BBB
2 20 20 CCC
3 30 (null) (null)
| |
2、再對中間表過濾
where 條件:
tab2.name=’AAA’
tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
第二條SQL的過程:
1、中間表
on條件:
tab1.size = tab2.size and tab2.name=’AAA’
(條件不為真也會傳回左表中的記錄) tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 (null) (null)
3 30 (null) (null)
其實以上結果的關鍵原因就是left join,right join,full join的特殊性,不管on上的條件是否為真都會傳回left或right表中的記錄,full則具有left和right的特性的并集。而inner jion沒這個特殊性,則條件放在on中和where中,傳回的結果集是相同的。
外連結比對,内連接配接過濾,外連結即比對又過濾用on和where搭配
7.圖解SQL的内連接配接與外連接配接
内外連接配接就相當于多個業務表的一次合體,連接配接的條件必須是關鍵性的!連接配接成功就可看成一張表!
在oracle的SQL語句常用的連接配接有内連接配接(inner join),外連接配接(outer join)等,内連接配接又包括等值連接配接,非等值連接配接,自連接配接;而外連接配接又分為左連接配接和右連接配接。其中預設的是内連接配接的等值連接配接。
為了友善我們建立兩張最簡易的表A、B,具體的表結構參看下面,來分析内連接配接與外連接配接的差別
一對多關系,A一(主表),B多(子表),主表的一條記錄對應子表的多條記錄
圖1 圖2
兩個表要做連接配接,必須要有連接配接字段,而在表A和表B中連接配接字段是Aid和Bnamid,下圖說明了連接配接之間關系圖3
圖3
(1) 内連接配接:利用内連接配接(等值)就可擷取藍色的公共部分C,即圖3中的資料集C,結果集為如下:
隻顯示主表與子表有關聯的記錄,一個主表記錄可能有多個子表記錄(即在生成的中間表中,主表資料一般重複出現,是以查詢出來的記錄數根據每個主表記錄有多少個子表記錄而定,下同)
圖4
其實select * from A join B on A.Aid=B.Bnamid;等價于select * from A,B where A.Aid=B.Bnamid;
注:非等值連接配接主要的話是針對一個範圍來查詢資料,自連接配接主要就是把1張表堪稱兩張表來用
(2)外連接配接:分為左外連接配接(left join)與右外連接配接(right join)
左外連接配接即公共顯示的藍色部分C1+顯示黃色的記錄集A1,顯示語句等價于select * from A,B where A.Aid=B.Bnamid(+);
不但顯示主表與子表有關聯的記錄,還顯示主表與子表沒有關聯的主表記錄
圖 5
右外連接配接即公共顯示的藍色部分C1+顯示綠色的B1,顯示語句等價于select * from A,B where A.Aid(+)=B.Bnamid;
顯示子表在主表有關聯的記錄,還顯示子表與主表沒有關聯的子表記錄
圖6
表A和表B情況是相對的,以上實驗都是A在左邊的情況,其實A left join B與B right join A的情況的結果集是一樣的。
兩表之間,隻要有關聯,不管以什麼關系存在,都可能有對方關聯或被關聯不到的資料,這就是區分内外連接配接的關鍵,資料的展示以關聯的一方為準,被關聯的可能重複被關聯
以哪個表為準,就顯示這個表的全部資訊,抛去另一個表獨有的部分
這是僅僅的技術層面,至于要以哪個表為準,要看業務邏輯的需要,哪個表的獨有部分是我們更想要的,這時候,表之間的對應關系才更重要點,這是業務問題
利用關鍵性的資料庫字段連接配接,才能更好地關聯
8.SQL何時使用内外連接配接
所謂内外連接配接,就是表與表有條件的拼接,内連接配接是連接配接條件所列字段,(比如a.recorder = b.userid中的recorder與userid)有值且滿足表達式的記錄才拼接成功并顯示,外連結的左外連結,連接配接條件是給右表說的,連接配接表達式成立的記錄與左表拼接,不成立的行不顯示,不管拼接表達式是否成立,左表照常顯示,
連接配接條件不受限制,并不是必須有主表,也可以是和主表連接配接的其他表組成連接配接條件
需要查找兩張表同時存在的資料,使用内連接配接,需要查找兩張表中一張表存在,另一張表不存在的時候使用外連接配接。
SELECT T1.C1,T2.CX,T3.* --如果沒有要求特别顯示哪個字段,則所有表的字段都顯示
FROM TAB1 T1
INNER JOIN TAB2 T2 ON (T1.C1=T2.C2)
LEFT JOIN TAB3 T3 ON (T1.C1=T2.C3)--不管和哪個表組成連接配接條件,隻要表達式成立的記錄,才能和主表拼接并顯示。
LEFT JOIN TAB4 T4 ON(T3.C2=T4.C3);
比如有tableA ,tableB,tableA和tableB是一對多
需求:根據tableB的某寫字段,查詢出tableA
分析:如果此時使用内連結 則相應的語句是:
select a.* from tableA a ,tableB b where a.id =tableB.aid and b.code='4401'
此時傳回的結果是tableA在tableB有子資料的部分資料,而如果表tableA中的某條資料,在表tableB中不存在子資料,此時是查詢不出來!
如果使用的是外連接配接,則相應的語句如下:
select a.* from tableA a left join tableB b on a.id=b.aid and b.code='4401';
此時傳回的結果是tableA中的全部資料,而且有重複數出現,則應該用distinct過濾,語句如下:
select distinct a.* from tableA a left join tableB b on a.id=b.aid and b.code='4401';
内聯接查詢可以連接配接兩個或兩個以上的表,參與内聯接的表的地位是平等的,
而外聯接中參與聯接的表有主從之分.以主表的每行資料去比對從表的資料列,符合條件的資料将直接傳回到結果集中,不符合的用NULL(空值)填充後再傳回到結果集中.
介紹2
内連接配接的查詢結果都是滿足連接配接條件的元組。但有時我們也希望輸出那些不滿足連接配接條件的元組資訊。比如,
有學生表與選課表
我們想知道每個學生的選課情況(每個學生有唯一的學号),包括已經選課的學生(這部分學生的學号在學生表中有,在選課表中也有,是滿足連接配接條件的),也包括沒有選課的學生(這部分學生的學号在學生表中有,但在選課表中沒有,不滿足連接配接條件),這時就需要使用外連接配接。外連接配接是隻限制一張表中的資料必須滿足連接配接條件,而另一張表中的資料可以不滿足連接配接條件的連接配接方式。3種外連接配接:
1)左外連接配接(LEFTOUTER JOIN)
如果在連接配接查詢中,連接配接管子左端的表中所有的元組都列出來,并且能在右端的表中找到比對的元組,那麼連接配接成功。如果在右端的表中,沒能找到比對的元組,那麼對應的元組是空值(NULL)。這時,查詢語句使用關鍵字LEFT OUTERJOIN,也就是說,左外連接配接的含義是限制連接配接關鍵字右端的表中的資料必須滿足連接配接條件,而不關左端的表中的資料是否滿足連接配接條件,均輸出左端表中的内容。
例如:要查詢所有學生的選課情況,包括已經選課的和還沒有選課的學生,查詢語句為
SELECT學生表.學号,姓名,班級,課程号,成績
FROM學生表LEFT OUTER JOIN選課表ON學生表.學号=選課表.學号
左外連接配接查詢中左端表中的所有元組的資訊都得到了保留。
2)右外連接配接(RIGHTOUTERJOIN)
右外連接配接與左外連接配接類似,隻是右端表中的所有元組都列出,限制左端表的資料必須滿足連接配接條件,而不管右端表中的資料是否滿足連接配接條件,均輸出表中的内容。
例如:同上例内容,查詢語句為
SELECT學生表.學号,姓名,班級,課程号,成績
FROM學生表RIGHTOUTERJOIN選課表ON學生表.學号=選課表.學号
右外連接配接查詢中右端表中的所有元組的資訊都得到了保留。
3)全外連接配接(FULL OUTER JOIN)
全外連接配接查詢的特點是左、右兩端表中的元組都輸出,如果沒能找到比對的元組,就使用NULL來代替。
例如:同左外連接配接例子内容,查詢語句為
SELECT學生表.學号,姓名,班級,課程号,成績
FROM學生表FULL OUTER JOIN選課表ON學生表.學号=選課表.學号
全外連接配接查詢中所有表中的元組資訊都得到了保留。
答案
你首先是要搞清楚外連接配接和内連接配接的概念之後就很容易進行判斷了,你要将兩個表比對的記錄都選取出來那麼就是内連接配接, 你要将除了兩表比對之外還需要其中某一個表不比對的記錄,那麼就用外連接配接,是左還是右取決于那個表是放在左邊還是右邊。
簡單說就是以誰為準就用誰!以左資料為準去找滿足條件的右資料,就用左外連;以右資料為準去找滿足條件的左資料,就用右外連;
内連接配接:取的兩個表的(有能連接配接的字段),的交集,即字段相同的。利用内連接配接可擷取兩表的公共部分的記錄
左外連接配接 就是以A表學生資料為準,去找B表内容或合并出另一個内容。
轉載自:https://blog.csdn.net/qq877507054/article/details/52328017