SQL เข้าร่วมในความสัมพันธ์แบบหนึ่งต่อกลุ่มโดยไม่มีความสัมพันธ์ใดที่ตรงกับค่าที่กำหนด

สมมติว่าฉันมีโต๊ะสองโต๊ะ

User
-----
id
first_name
last_name

User_Prefs
-----
user_id
pref

ข้อมูลตัวอย่างใน User_Prefs อาจเป็นได้

user_id | pref
  2     |  SMS_NOTIFICATION
  2     |  EMAIL_OPT_OUT
  2     |  PINK_BACKGROUND_ON_FRIDAYS

และผู้ใช้บางรายอาจไม่มีแถวที่สอดคล้องกันใน User_Prefs

ฉันต้องค้นหาชื่อและนามสกุลของผู้ใช้ที่ไม่มี EMAIL_OPT_OUT เป็นหนึ่งในแถว User_Pref (อาจมีหลายแถวหรืออาจไม่มีก็ได้)

SELECT DISTINCT u.* from User u
LEFT JOIN User_Prefs up ON (u.id=up.user_id)
WHERE up.pref<>'EMAIL_OPT_OUT'

ทำให้ฉันเข้าใจทุกคนที่มีอย่างน้อยหนึ่งแถวที่ไม่ใช่ "EMAIL_OPT_OUT" ซึ่งแน่นอนว่าไม่ใช่สิ่งที่ฉันต้องการ ฉันต้องการให้ทุกคนไม่มีแถวที่ตรงกับ "EMAIL_OPT_OUT"

มีวิธีให้ประเภทการรวมและเงื่อนไขการรวมกรองแถวที่ฉันต้องการละไว้ที่นี่หรือไม่ หรือฉันต้องการแบบสอบถามย่อย?


person Jacob Mattison    schedule 20.07.2010    source แหล่งที่มา
comment
สิ่งนี้อาจช่วยได้ explainexted.com/2009/09/15/   -  person Francisco    schedule 21.07.2010


คำตอบ (2)


โดยส่วนตัวแล้วฉันคิดว่าอนุประโยคประเภท "ที่ไม่มีอยู่" อาจจะอ่านได้ง่ายกว่า แต่นี่คือแบบสอบถามที่มีการเข้าร่วมซึ่งทำสิ่งเดียวกัน

select distinct u.* from User u
left join User_Prefs up ON u.id = up.user_id and up.pref = 'EMAIL_OPT_OUT'
where up.user_id is null
person Mayo    schedule 20.07.2010
comment
+1 สิ่งสำคัญที่ควรทราบที่นี่คือ คุณสามารถเข้าร่วมตามเกณฑ์ใดก็ได้ และรวมเกณฑ์เข้าด้วยกัน คุณไม่ได้ถูกจำกัดอยู่เพียงการเข้าร่วมคีย์ที่ตรงกัน - person Marcus Adams; 21.07.2010
comment
+1 - ฉันชอบสิ่งนี้มากกว่าคำตอบของฉัน เกือบจะเร็วกว่าเช่นกัน - person Eric Petroelje; 21.07.2010
comment
สิ่งที่ฉันกำลังมองหาอย่างแน่นอน ฉันก็สนิทกันมากเหมือนกัน เพียงแต่ไม่มีคลื่นสมองในการเข้าร่วมอย่างเท่าเทียมกัน แทนที่จะไม่เท่าเทียมกัน - person Jacob Mattison; 21.07.2010
comment
สำหรับคำอธิบายว่าเหตุใดเวอร์ชันดั้งเดิมจึงใช้งานไม่ได้ โปรดดูที่: wiki.lessthandot.com /index.php/WHERE_conditions_on_a_LEFT_JOIN - person HLGEM; 21.07.2010

ทำไมไม่เก็บค่ากำหนดผู้ใช้ของคุณไว้ในตารางผู้ใช้เป็นเขตข้อมูลบูลีน? สิ่งนี้จะทำให้การค้นหาของคุณง่ายขึ้นอย่างมาก

SELECT * FROM User WHERE EMAIL_OPT_OUT = false
person Marcus Adams    schedule 20.07.2010
comment
ฉันไม่หวังว่าฉันจะเปลี่ยนสคีมา นี่ไม่ใช่ฐานข้อมูลของฉัน จริงๆ แล้วฉันกำลังเข้าร่วมเพื่อดูมุมมองที่มาจากฐานข้อมูลที่เป็นกรรมสิทธิ์ แม้ว่าฉันจะชี้ให้เห็นว่าแนวทางของคุณมีข้อเสียคือชุดของตัวเลือกที่เป็นไปได้จะต้องมีฮาร์ดโค้ดในสคีมาฐานข้อมูล - person Jacob Mattison; 21.07.2010
comment
นอกจากนี้ยังจะทำให้การบำรุงรักษาเมื่อคุณต้องการเพิ่มประเภทใหม่มีความซับซ้อนมากขึ้น ตารางที่เกี่ยวข้องตามที่โปสเตอร์มีคือการออกแบบที่ถูกต้อง - person HLGEM; 21.07.2010
comment
@HLGEM ฉันไม่เห็นด้วยกับปัญหาการบำรุงรักษา แต่ฉันใช้ MVC ซึ่งสรุปเนื้อหาทั้งหมดนี้ - person Marcus Adams; 21.07.2010