เลือก * ไม่มีอยู่ที่ไหน


98

ฉันคิดว่าฉันจะไปในเส้นทางที่ถูกต้องกับสิ่งนี้ ... โปรดอดทนกับฉันเพราะ SQL ของฉันไม่ได้ใหญ่ที่สุด

ฉันพยายามสืบค้นฐานข้อมูลเพื่อเลือกทุกอย่างจากตารางหนึ่งที่ไม่มีเซลล์บางเซลล์อยู่ในอีกตารางหนึ่ง มันไม่สมเหตุสมผลมากนัก แต่ฉันหวังว่าโค้ดชิ้นนี้จะเป็นเช่นนั้น

SELECT * from employees WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

โดยพื้นฐานแล้วฉันมีโต๊ะเดียวที่มีรายชื่อพนักงานและรายละเอียดของพวกเขา จากนั้นตารางอื่นที่มีรายละเอียดอื่น ๆ รวมถึงชื่อ ในกรณีที่ไม่มีชื่ออยู่ในตาราง eotm_dyn หมายความว่าไม่มีรายการสำหรับพวกเขาฉันต้องการดูว่าพวกเขาเป็นใครหรือกล่าวอีกนัยหนึ่งคือดูว่ามีอะไรหายไป

ข้อความค้นหาข้างต้นไม่คืนค่าอะไรเลย แต่ฉันรู้ว่ามี 20 ชื่อที่หายไปดังนั้นฉันจึงไม่เข้าใจถูก

ใครสามารถช่วย?

คำตอบ:


163

คุณไม่ได้เข้าร่วมตารางในแบบสอบถามของคุณ

ข้อความค้นหาเดิมของคุณจะไม่คืนค่าใด ๆ เลยเว้นแต่จะไม่มีบันทึกเลยeotm_dynซึ่งในกรณีนี้จะส่งคืนทุกอย่าง

สมมติว่าควรรวมตารางเหล่านี้employeeIDให้ใช้สิ่งต่อไปนี้:

SELECT  *
FROM    employees e
WHERE   NOT EXISTS
        (
        SELECT  null 
        FROM    eotm_dyn d
        WHERE   d.employeeID = e.id
        )

คุณสามารถเข้าร่วมตารางเหล่านี้มีLEFT JOINคำหลักและกรองออกNULLมา NOT EXISTSแต่ตอนนี้มีแนวโน้มที่จะมีประสิทธิภาพน้อยกว่าการใช้


31
ฉันต้องการ "ที่ที่ไม่อยู่" ปีละสองครั้งและฉันมักจะลืมวิธีการใช้งาน ขอบคุณ - ตัวอย่างนี้จะถูกบุ๊กมาร์กทันที
Mateng

1
มีใครช่วยอ้างอิงสำหรับ "LEFT JOIN + NULL filter มีประสิทธิภาพน้อยกว่า NOT EXISTS" สามารถเห็นได้ชัด แต่ฉันไม่เคยเห็นสิ่งนั้นในเอกสาร ขอบคุณ.
toni07

2
@ toni07 ที่จริงคือตำนาน LEFT JOIN ชนะ explainextended.com/2009/09/18/... .. บล็อก Quassnoi คือมักจะเป็นแหล่งข้อมูลที่เป็นประโยชน์
Kaii

ฉันจะใช้สิ่งนี้ใน HAVING clause ได้อย่างไร akagroup by X having exist [row with employeeID = e.id]
phil294

@blauhirn: เช่นนั้น
Quassnoi

85
SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn)

หรือ

SELECT * FROM employees WHERE NOT EXISTS (SELECT * FROM eotm_dyn WHERE eotm_dyn.name = employees.name)

หรือ

SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL

1
NB! NOT INไม่ทำงานตามที่คาดไว้หากnameมีnullค่า ดูจาก 20sec 36min ในวิดีโอSESSION: 10 แบบสอบถามการปรับแต่งเทคนิคทุก SQL Programmer ควรรู้ (เควินไคลน์, แอรอนเบอร์ทรานด์)
hlovdal

12

คุณสามารถทำการ JOIN ด้านซ้ายและยืนยันว่าคอลัมน์ที่เข้าร่วมเป็นโมฆะ

ตัวอย่าง:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL

8
SELECT * from employees
WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

ไม่ส่งคืนระเบียนใด ๆ เว้นแต่eotm_dynจะว่างเปล่า คุณต้องมีเกณฑ์บางอย่างในการSELECT name FROM eotm_dynชอบ

SELECT * from employees
WHERE NOT EXISTS (
    SELECT name FROM eotm_dyn WHERE eotm_dyn.employeeid = employees.employeeid
)

สมมติว่าทั้งสองตารางเชื่อมโยงกันด้วยความสัมพันธ์ของ Foreign Key ณ จุดนี้คุณสามารถใช้ตัวเลือกอื่น ๆ ได้มากมายรวมถึง LEFT JOIN อย่างไรก็ตามเครื่องมือเพิ่มประสิทธิภาพมักจะจัดการพวกมันเหมือนกันในกรณีส่วนใหญ่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.