Exists
EXISTS運算子用於判斷查詢子句是否有記錄,如果有一筆或多筆記錄存在回傳 True,否則傳回 False。 (該子查詢實際上並不返回任何數據,而是返回值True或False)
EXISTS與IN的使用效率的問題,通常採用exists要比in效率高,因為IN不走索引,但要看實際情況具體使用:
- 當內表小外表大時,
EXISTS的效率<in的效率;- 當內表大外表小時,
EXISTS的效率>in的效率。 總結一下就是,內表小用in,外表小用EXISTS。 (內表小用in,內表大用exists)
語法
1
exists (subquery)
subquery 是受限的 SELECT 語句 (不允許有 COMPUTE 子句和 INTO 關鍵字)。
1
2
3
select ...
from ...
where exists (subquery)
該語法可以理解為:將主查詢的數據,放到子查詢中做條件驗証,根據驗証結果(True 或 False)來作為主查詢的數據結果是否得以保留。
要注意的是,
EXISTS和NOT EXISTS只判斷子查詢是否回傳結果,而不關心結果的特定內容。使用時,子查詢可以與主查詢的欄位進行關聯,以便根據子查詢的結果進行篩選和篩選。
原理
exists(sql返回結果集為真)not exists(sql不返回結果集為真或返回結果集為假)
1
2
select * from a where exists (select * from b where a.id = b.id)
select * from a where not exists (select * from b where a.id = b.id)
sql語句使用了 exists或 not exists 後的執行順序是:先執行「外查詢」再執行「內查詢」。 (這和學的子查詢概念就”衝突了” XD)
執行步驟 (使用exists)
執行順序是:先執行外查詢,再執行子查詢
- 首先執行「外查詢」 select * from a,然後從「外查詢」的資料取出一條資料傳給「內查詢」。
- 「內查詢」執行 select * from b,「外查詢」傳入的資料和「內查詢」獲得資料根據
where後面的條件做匹對,如果存在資料滿足a.id=b.id則返回true,如果一條都不滿足則返回false。 - 「內查詢」返回
true,則「外查詢」的這行資料保留,反之「內查詢」返回false則「外查詢」的這行資料不顯示。「外查詢」的所有資料逐行查詢匹對。
not exists和exists的用法相反,
Exists: 強調的是是否返回結果集,不要求知道返回什麼,比如: select name from student where sex = ‘m’ and mark exists(select 1 from grade where …) ,只要exists引導的子句有結果集返回,那麼exists這個條件就算成立了,大家注意返回的欄位始終為1,如果改成”select 2 from grade where …“,那麼返回的欄位就是2,這個數字沒有意義。所以exists子句不在乎返回什麼,而是在乎是不是有結果集返回。
範例一:在子查詢中使用 NULL,仍會傳回結果集
Select Null
1
2
3
select *
from Customers
where exists(select null)
同等於:select * from Customers
因為
NULL在資料庫中是一個值(它是一個未知的值),在出現NULL值的地方EXISTS結構都會傳回真。
Where 1=1、 Select 1、select null
由於EXISTS結構的工作原理,所以下面的語句所實現的功能是一樣的。 同等於:select * from a
1
2
select * from a
where exists(select 1)
1
2
select * from a
where exists(select null)
1
2
select * from a
where 1=1
範例二:Exists
顯示有販賣業績的負責人之負責人ID與負責人姓名
1
2
3
4
5
--顯示有販賣業績的負責人之負責人ID與負責人姓名
select A.負責人ID, A.負責人姓名
from [負責人清單] A
where exists
(select 1 from [販賣資料] B where B.負責人ID = A.負責人ID)
執行結果
1
2
3
4
5
6
7
8
負責人ID 負責人姓名
1 鈴木
2 小野
3 齋藤
5 小林
6 伊藤
7 佐瀨
8 宇賀神
範例三: Not Exists
NOT EXISTS 的作用與 EXISTS 相反。 如果子查詢未傳回任何資料列,便滿足 NOT EXISTS 中的 WHERE 子句。
顯示沒有販賣業績的負責人之負責人ID與負責人姓名
1
2
3
4
5
--顯示沒有販賣業績的負責人之負責人ID與負責人姓名
select A.負責人ID, A.負責人姓名
from [負責人清單] A
where not exists
(select 1 from [販賣資料] B where B.負責人ID = A.負責人ID)
執行結果
1
2
3
負責人ID 負責人姓名
4 藤本
9 岡田
範例四:Exists + Except 差集
取得包含於負責人清單,但不包含分店負責人清單中的負責人的總販賣業績(販賣單價*數量)。(差集,可以使用Except)
1
2
3
4
5
6
7
8
9
10
--取得包含於負責人清單,但不包含分店負責人清單中的負責人的總販賣業績(販賣單價*數量)
select sum(B.販賣單價*A.數量) "總業績"
from [dbo].[販賣資料] A
join [dbo].[商品清單] B on B.商品ID = A.商品ID
where exists
(
select [負責人ID] from [dbo].[負責人清單]
except
select [分店負責人ID] from [dbo].[分店負責人清單]
)
執行結果
1
2
總業績
4625000
Select 1、Select Null
select 1、select unll一般用來當條件使用,比如:
exists(select 1 from table)exists(select null from table)
MSDN Exists [SQL] Select 1、Select null SQL笔记-select 1与select null [SQL] SQL語句的執行順序、EXISTS執行順序、EXISTS和IN執行效率