มันอาจจะได้ข้อสรุปจากคำตอบที่นี่ที่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 ซัพพลายเออร์ที่รู้จักกันในการจัดหาชิ้นส่วนในปริมาณที่รู้จักกัน
สังเกตอาจมีควรจะเป็นข้อ จำกัด ที่สำคัญต่างประเทศที่อ้างอิงspqsp
ผลลัพธ์สามารถรับได้โดยใช้ตัวดำเนินการสัมพันธ์ 'ลบ' (เป็น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การเปลี่ยนแปลงพฤติกรรมเชิงความหมายของการไม่ได้อยู่ในชุดนี้เป็นอย่างอื่น?