SQLSERVER 交、並、差集,In,Not In,Exist,Not Exist的區別,四種連接(轉載)

原文鏈接:https://blog.csdn.net/weixin_46879188/article/details/119652042

一、SQLServer 交(intersect)、並(union)、差(except)集合運算
SQLServer中通過intersect,union,except和三個關鍵字對應交、並、差三種集合運算。
他們的對應關係可以參考下面圖示


前提條件:

兩個查詢的結果集的規則:
兩個查詢中列的數量和順序必須相同。相應列的數據類型必須相同或兼容。列名可以不一樣。

1 Union 取合集並過濾重複數據
SELECT * FROM A
UNION
SELECT * FROM B;

2 Union all 取合集不過濾重複數據
SELECT * FROM A
UNION all
SELECT * FROM B;

3 Intersect 取交集(兩個表中都有數據)
SELECT * FROM A
Intersect
SELECT * FROM B;

4 except 取差集(取A-B的記錄)
SELECT * FROM A
except
SELECT * FROM B;

 

二、SQLServer 四種連接
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
完整外部聯接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結果集行包含基表的數據值。

在數據庫中使用連接有兩種方式:使用join關鍵字,另一種是使用(+)這種方式
例子:
a表

id name
1 張3
2 李四
3 王武
b表

id job parent_id
1 23 1
2 34 2
3 34 4
a.id同parent_id 存在關係

1) 內連接
select a.*,b.* from a inner join b on a.id=b.parent_id

或者是:

select a.*,b.* from a,b where a.id=b.parent_id

結果是

a.id a.name b.id b.job 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

結果是

a.id a.name b.id b.job b.parent_id
1 張3 1 23 1
2 李四 2 34 2
3 王武 null null null
3) 右連接
select a.*,b.* from a right join b on a.id=b.parent_id

結果是

a.id a.name b.id b.job b.parent_id
1 張3 1 23 1
2 李四 2 34 2
null null 3 34 4
4) 完全連接
select a.*,b.* from a full join b on a.id=b.parent_id

結果是

a.id a.name b.id b.job b.parent_id
1 張3 1 23 1
2 李四 2 34 2
null null 3 34 4
3 王武 null null null

 


三、SQLServer IN和EXISTS、not in 和not exists的效率詳解
in 和 exists

如果查詢的兩個表大小相當,那麼用in和exists差別不大。

如果兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in:

例如:表A(小表),表B(大表)
1:
select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。

相反的
2:
select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。

not in 和not exists

如果查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;
而not extsts 的子查詢依然能用到表上的索引。
所以無論那個表大,用not exists都比not in要快。
也就是說,in和exists需要具體情況具體分析,not in和not exists就不用分析了,儘量用not exists就好了。

結論:
區別
① 集合是關聯條件是Select中的字段。輸出結果集是Select中的字段。
四種連接(not in,not Exist)是關聯條件是Where中的字段。輸出結果集是Select中字段。

聯繫

① 集合是對行的篩選,四種連接(not in,not Exist)也是對行的篩選。

②交集 和內連接 功能類似,求交集。

③並集union 和全連接 功能類似,求並集。

④差集 和(not in,not Exist) 功能類似,求差集。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章