SQL - 內連接與外連接


PDF下載地址:SQL-內連接與外連接.pdf

連接查詢在關系型數據庫中經常用到,是多表聯合查詢的基礎。
主要包含:內連接外連接交叉連接

 


內連接

內連接又分為等值連接不等值連接自然連接

連接查詢中使用的比較運算符有:=, >, <, <>, >=, <=, !>, !<

等值連接

等值連接使用”=”來進行比較運算。
請看下面的例子:

student_id student_name class_id
1 aaa 15
2 bbb 16
3 ccc 17

 

class_id class_name
15 五班
16 六班
17 七班
18 八班

如果需要查出一下內容:

每個學生所對應的班級名稱

此時就可用以下sql語句:

SELECT * FROM
T_student ts,T_class tc
WHERE
ts.class_id=tc.class_id

或者:

SELECT * FROM
T_student ts inner join T_class tc
ON
ts.class_id = tc.class_id

查詢結果如下:

student_id student_name class_id class_id class_name
1 aaa 15 15 五班
2 bbb 16 16 六班
3 ccc 17 17 七班

結論如下:

等值連接:

若要連接表t1和t2,比較條件為t1.a=t2.a,那么數據庫會用t1中a列的所有元素逐個和t2中的a進行比較,如果相等,則輸出該行。

至於數據庫內部如何實現,我們暫且不去深究。

不等值連接

內連接中,不使用”=”作為比較運算符,就叫不等值連接。
如果需要查詢以下內容:

T_student表和T_class表中,class_id字段不相等的所有組合

此時就可用以下sql語句:

SELECT * FROM
T_student ts,T_class tc
WHERE
ts.class_id <> tc.class_id

或者:

SELECT * FROM
T_student ts inner join T_class tc
ON
ts.class_id <> tc.class_id

查詢結果如下:

student_id student_name class_id class_id class_name
2 bbb 16 15 六班
3 ccc 17 15 七班
1 aaa 15 16 五班
3 ccc 17 16 七班
1 aaa 15 17 五班
2 bbb 16 17 六班
1 aaa 15 18 五班
2 bbb 16 18 六班
3 ccc 17 18 七班

結論如下:

不等值連接

若要連接表t1和t2,比較條件為t1.a不等於t2.a,那么數據庫會用t1中a列的所有元素逐個和t2中的a進行比較,如果不相等,則輸出該行。

自然連接

自然連接是一種特殊的等值連接,和等值連接差不多,區別在於:

自然連接會去掉重復的列;
自然連接要求比較的兩個列屬性必須相同,等值連接則不需要;

如果需要查出以下內容:

每個學生所對應的班級名稱

sql語句和等值連接差不多:

SELECT ts.*,tc.class_name FROM
T_student ts inner join T_class tc
ON
ts.class_id = tc.class_id

查詢結果如下:

student_id student_name class_id class_name
1 aaa 15 五班
2 bbb 16 六班
3 ccc 17 七班

由此可見:

自然連接相當於在等值連接的基礎上,加了顯示的限定條件,從而實現列去重

外連接

外連接又分為左連接右連接全連接

左連接

左連接以左表為基礎,顯示左表中的所有記錄(顯示的記錄條數=左表中記錄的條數)。再用左表中的指定列來和右表中的指定列比較,滿足則輸出值,不滿足則輸出NULL
如果需要查出以下內容:

每個學生所對應的班級名稱

此時就可用以下sql語句:

SELECT * FROM
T_student ts left join T_class tc
ON
ts.class_id = tc.class_id

查詢結果如下:

student_id student_name class_id class_id class_name
1 aaa 15 15 五班
2 bbb 16 16 六班
3 ccc 17 17 七班

但如果T_student表中增加一條字段:

student_id student_name class_id
4 ddd 20

此時再用上一條sql語句查詢,則結果變為:

student_id student_name class_id class_id class_name
1 aaa 15 15 五班
2 bbb 16 16 六班
3 ccc 17 17 七班
4 ddd 20 NULL NULL

結論如下:

左連接

以左表為基礎,顯示的記錄條數=左表中記錄條數。如果左表中選出的字段符合條件則顯示,否則顯示NULL

右連接

與左連接恰恰相反。以右表為基礎,顯示記錄的條數=右表中記錄條數,然后和左表中的字段比較,符合條件則輸出,否則輸出NULL
使用以下sql語句:

SELECT * FROM
T_student ts right join T_class tc
ON
ts.class_id = tc.class_id

查詢結果為:

student_id student_name class_id class_id class_name
1 aaa 15 15 五班
2 bbb 16 16 六班
3 ccc 17 17 七班
NULL NULL NULL 18 八班

結論如下:

右連接

以右表為基礎,顯示記錄的條數=右表中記錄條數。如果左表中選出的字段符合條件則顯示,否則顯示NULL

全連接

全連接類似於左連接和右連接的綜合,顯示記錄的條數=指定比較字段在兩個表中的不同種類數。對於空余字段則顯示NULL
使用以下sql語句:

SELECT * FROM
T_student ts full join T_class tc
ON
ts.class_id = tc.class_id

查詢結果為:

student_id student_name class_id class_id class_name
1 aaa 15 15 五班
2 bbb 16 16 六班
3 ccc 17 17 七班
NULL NULL NULL 18 八班

但如果T_student表中增加一條字段:

student_id student_name class_id
4 ddd 20

此時再用上一條sql語句查詢,則結果變為:

student_id student_name class_id class_id class_name
1 aaa 15 15 五班
2 bbb 16 16 六班
3 ccc 17 17 七班
4 ddd 20 NULL NULL
NULL NULL NULL 18 八班

結論如下:

全連接

指定比較字段在兩個表中的不同種類數。對於空余字段則顯示NULL

交叉連接

交叉連接很簡單,就是兩個表做笛卡爾積
如果不加where做選擇比較,那么顯示的記錄行數就是兩個表行數的乘積。
使用以下sql語句:

SELECT * FROM
T_student cross join T_class

或者:

SELECT * FROM
T_student,T_class

查詢結果為:

student_id student_name class_id class_id class_name
1 aaa 15 15 五班
2 bbb 16 15 六班
3 ccc 17 15 七班
1 aaa 15 16 五班
2 bbb 16 16 六班
3 ccc 17 16 七班
1 aaa 15 17 五班
2 bbb 16 17 六班
3 ccc 17 17 七班
1 aaa 15 18 五班
2 bbb 16 18 六班
3 ccc 17 18 七班

如果是有where進行選擇,那就先進行笛卡爾積,然后在笛卡爾積的結果中進行選擇(效率很差)。
結論如下:

交叉連接

沒有where進行選擇,結果為兩個表的笛卡爾積
where進行選擇,先做笛卡爾積,在笛卡爾積的結果中進行選擇



 
 


免責聲明!

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



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