มันอาจจะได้ข้อสรุปจากคำตอบที่นี่ที่NOT IN (subquery)
ไม่ได้จัดการ nulls NOT EXISTS
อย่างถูกต้องและควรหลีกเลี่ยงในความโปรดปรานของ อย่างไรก็ตามข้อสรุปดังกล่าวอาจจะคลอดก่อนกำหนด ในสถานการณ์ต่อไปนี้ให้เครดิตกับ Chris Date (การเขียนโปรแกรมฐานข้อมูลและการออกแบบ, Vol 2 No 9, กันยายน 1989), มันเป็นNOT IN
สิ่งที่จัดการ nulls อย่างถูกต้องและส่งกลับผลลัพธ์ที่ถูกต้องมากกว่าNOT EXISTS
อย่างถูกต้องและผลตอบแทนผลที่ถูกต้องมากกว่า
พิจารณาตารางsp
เพื่อเป็นตัวแทนซัพพลายเออร์ ( sno
) ที่รู้จักกันในการจัดหาชิ้นส่วน ( pno
) ในปริมาณ ( qty
) ตารางนี้มีค่าต่อไปนี้:
VALUES ('S1', 'P1', NULL),
('S2', 'P1', 200),
('S3', 'P1', 1000)
โปรดทราบว่าปริมาณเป็นโมฆะคือเพื่อให้สามารถบันทึกข้อเท็จจริงที่ซัพพลายเออร์เป็นที่รู้จักในการจัดหาชิ้นส่วนแม้ว่ามันจะไม่เป็นที่รู้จักในปริมาณใด
งานคือการค้นหาซัพพลายเออร์ที่เป็นที่รู้จักหมายเลขชิ้นส่วนอุปทาน 'P1' แต่ไม่ได้อยู่ในปริมาณ 1,000
การใช้งานต่อไปนี้NOT IN
เพื่อระบุซัพพลายเออร์ 'S2' อย่างถูกต้องเท่านั้น:
WITH sp AS
( SELECT *
FROM ( VALUES ( 'S1', 'P1', NULL ),
( 'S2', 'P1', 200 ),
( 'S3', 'P1', 1000 ) )
AS T ( sno, pno, qty )
)
SELECT DISTINCT spx.sno
FROM sp spx
WHERE spx.pno = 'P1'
AND 1000 NOT IN (
SELECT spy.qty
FROM sp spy
WHERE spy.sno = spx.sno
AND spy.pno = 'P1'
);
อย่างไรก็ตามการสืบค้นด้านล่างใช้โครงสร้างทั่วไปเดียวกัน แต่มีNOT EXISTS
แต่ไม่ถูกต้องรวมถึงซัพพลายเออร์ 'S1' ในผลลัพธ์ (เช่นซึ่งปริมาณเป็นโมฆะ):
WITH sp AS
( SELECT *
FROM ( VALUES ( 'S1', 'P1', NULL ),
( 'S2', 'P1', 200 ),
( 'S3', 'P1', 1000 ) )
AS T ( sno, pno, qty )
)
SELECT DISTINCT spx.sno
FROM sp spx
WHERE spx.pno = 'P1'
AND NOT EXISTS (
SELECT *
FROM sp spy
WHERE spy.sno = spx.sno
AND spy.pno = 'P1'
AND spy.qty = 1000
);
ดังนั้นNOT EXISTS
ไม่ใช่กระสุนเงินที่มันอาจปรากฏขึ้น!
แน่นอนที่มาของปัญหาคือการมีโมฆะดังนั้นทางออก 'ของจริง' คือการกำจัดโมฆะเหล่านั้น
สามารถทำได้ (ในการออกแบบอื่น ๆ ที่เป็นไปได้) โดยใช้สองตาราง:
sp
ซัพพลายเออร์ที่รู้จักกันในการจัดหาชิ้นส่วน
spq
ซัพพลายเออร์ที่รู้จักกันในการจัดหาชิ้นส่วนในปริมาณที่รู้จักกัน
สังเกตอาจมีควรจะเป็นข้อ จำกัด ที่สำคัญต่างประเทศที่อ้างอิงspq
sp
ผลลัพธ์สามารถรับได้โดยใช้ตัวดำเนินการสัมพันธ์ 'ลบ' (เป็นEXCEPT
คำหลักใน SQL มาตรฐาน) เช่น
WITH sp AS
( SELECT *
FROM ( VALUES ( 'S1', 'P1' ),
( 'S2', 'P1' ),
( 'S3', 'P1' ) )
AS T ( sno, pno )
),
spq AS
( SELECT *
FROM ( VALUES ( 'S2', 'P1', 200 ),
( 'S3', 'P1', 1000 ) )
AS T ( sno, pno, qty )
)
SELECT sno
FROM spq
WHERE pno = 'P1'
EXCEPT
SELECT sno
FROM spq
WHERE pno = 'P1'
AND qty = 1000;
NOT IN
เป็นชุด<> and
การเปลี่ยนแปลงพฤติกรรมเชิงความหมายของการไม่ได้อยู่ในชุดนี้เป็นอย่างอื่น?