NOT IN/NOT EXISTS/EXCEPT 使用注意事項
#SQL
【SQL Tips】之【 NULL處理技巧,使用NOT IN /NOT EXISTS/EXCEPT】
許多時候,兩個資料表要找出差異值的時候,許多人第一直覺就是使用【NOT IN】,當然大部分時候都不會有狀況,但是碰到NOT IN的子查詢資料值,如果有NULL,就全盤皆輸,意思就是找不出任何差異。這樣在小量資料可以藉由眼力觀察的狀況下,還可以找出這樣寫法NOT IN的危險地方,但是碰到背景程式,或是資料量多的時候,幾乎無法觀察到這樣危險。所以,告訴自己不要再用【NOT IN】去找出兩邊資料差異。
反倒是要使用【NOT EXISTS】寫法,雖然是複雜一點,但是跨越SQL Server與Oracle兩種資料庫,都是可以正常找出兩邊資料差異值,不擔心NOT EXISTS的基礎資料表有NULL值狀況。另外值得一提就是,需多人會直接使用SQL Server的【EXCEPT】與Oracle的【MINUS】方式,要留意再留意,這樣的方式雖然可以找出差異值,但是針對回傳值,會自動進行重複資料列移除。
【SQL Server Code】
if object_id('x') is not null
drop table x
go
--建立比對基礎資料
create table x(a int)
go
insert into x values(1)
insert into x values(1) --注意重複
insert into x values(NULL) --注意NULL
go
if object_id('y') is not null
drop table y
go
--建立簡單比對來源資料
create table y(b int not null)
go
insert into y values(1)
insert into y values(1)
insert into y values(2)
insert into y values(2)
insert into y values(2) --注意三個2
go
--三種找出y資料表中(1,1,2,2,2) 然後不存在於 x資料表中的(1,1,null)
--【預期要回傳三個2】
--第一種 使用NOT IN 注意(子查詢有NULL值)
--無法處理對比資料表有NULL狀況
SELECT b
FROM y
WHERE b NOT IN(SELECT a from x)
GO
--第二種 使用NOT EXISTS 注意(SELECT 需要 JOIN)
--忠實回傳三個2
SELECT b
FROM y
WHERE NOT EXISTS (SELECT * FROM x WHERE x.a = y.b)
GO
--第三種 使用EXCEPT (僅回傳一個2)
SELECT b FROM y
EXCEPT
SELECT a FROM x
GO
【Oracle Code】
drop table x purge;
--建立比對基礎資料
create table x(a int);
insert into x values(1);
insert into x values(1); --注意重複
insert into x values(NULL); --注意NULL
drop table y purge;
--建立簡單比對來源資料
create table y(b int not null);
insert into y values(1);
insert into y values(1);
insert into y values(2);
insert into y values(2);
insert into y values(2); --注意三個2
--三種找出y資料表中(1,1,2,2,2) 然後不存在於 x資料表中的(1,1,null)
--第一種 使用NOT IN 注意(子查詢有NULL值)
--無法處理對比資料表有NULL狀況
SELECT b
FROM y
WHERE b NOT IN(SELECT a from x);
--第二種 使用NOT EXISTS 注意(SELECT 需要 JOIN)
--忠實回傳三個2
SELECT b
FROM y
WHERE NOT EXISTS (SELECT * FROM x WHERE x.a = y.b);
--第三種 使用EXCEPT (僅回傳一個2)
SELECT b FROM y
MINUS
SELECT a FROM x;
not exists sql 在 緯育TibaMe Facebook 八卦
🔥學習資料庫的第一步
🔥快速活用 MySQL,精準設計關聯式資料庫
新課早鳥特惠 👉 https://bit.ly/2L9YTzn
💭你是否有過以下問題?
⚠資料太雜亂,找不到重點
⚠資訊量超出自身負荷,不知道該如何統整或分類
⚠總是花很多時間搜尋資料,卻還是一團混亂
⚠大量資訊擺在眼前,卻不懂該怎麼活用
💭10項課程目標帶你完整學會SQL
🎯運用 Workbench 工具
🎯運用 SQL 語法
🎯建立資料庫、表格、資料
🎯子查詢 - IN、ANY、ALL、EXISTS
🎯查詢資料 - SELECT、ORDER BY、WHERE 語法
🎯邏輯運算 - AND、OR、NOT、BETWEEN、IN 語法
🎯MySQL 不同函式種類與應用
🎯管理使用者帳號與如何授權
🎯關聯式資料庫觀念並進行設計
🎯MySQL 語法並進行實作
快速活用 MySQL,精準設計關聯式資料庫
早鳥特惠 👉 https://bit.ly/2L9YTzn
#Windows與MacOS皆適用
#課程中包含多個範例
#不怕學不會 #只怕你不學
not exists sql 在 [SQL ] NOT EXISTS 雙重否定語法- 看板Database - 批踢踢實業坊 的八卦
資料庫名稱:
資料庫版本:
內容/問題描述:
大家好,我是從零開始準備考國考的商科資訊考生。
沒有實務經驗所以不太了解版本,抱歉。
目前在接觸基礎SQL習題有碰到一些問題,我是參閱聖經本第六版
Q1:列出參與所有專案的供應商名稱?
題目所給表格:
解法是用:不存在任何專案是沒有參與的
解答就像此網站的解析:https://goo.gl/fZwjDj
巢狀查詢是要視為FROM後面的表格一起看嗎?
為何第二個FROM後面是專案,最後一個FROM是看專案供應零件?
如果我先從最內層解析,
最後一個WHERE的條件是連結到兩個更外層查詢的表格(供應商和專案)
就代表我得同時看到最外層的 供應商.專案.專案供應零件 的表格
我的問題點在於要如何一步一步建立多層的巢狀查詢,由內向外、由外向內,或是同時?
這種巢狀查詢要怎麼練習呢?
------------------------------------------------------------------------------
另外,關於"所有"的sql語法,何時要用"負負得正"的方式來解(即不存在...沒有參與)
何時要用正向的存在方式來解(即存在)?
例如 Q2.列出所有有參與"一級棒供應商有參與的專案"的供應商
解答從"找出供應商其不存在任何一級棒參與的專案是沒有參與的"
PS.為何S2集合 MINUS S1集合 為空集合 代表兩者S1被包含於S2?
感謝各位,搞得我頭好痛= =
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.102.181.58
※ 文章網址: https://www.ptt.cc/bbs/Database/M.1528879019.A.353.html
... <看更多>