SQL-соединение по отношению один-ко-многим, где ни один из множества не соответствует заданному значению - PullRequest
5 голосов
/ 21 июля 2010

Скажем, у меня есть две таблицы

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.

Iнужно запросить имя и фамилию любого пользователя, который НЕ имеет 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".

Есть ли способ иметь тип соединения и условия соединения, чтобы отфильтровать строки, которые я хочу здесь опустить?Или мне нужен подзапрос?

Ответы [ 2 ]

11 голосов
/ 21 июля 2010

Лично я думаю, что предложение типа «где не существует» может быть проще для чтения, но вот запрос с объединением, который делает то же самое.

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
0 голосов
/ 21 июля 2010

Почему бы не сохранить ваши пользовательские настройки в пользовательской таблице в виде логических полей? Это значительно упростит ваши запросы.

SELECT * FROM User WHERE EMAIL_OPT_OUT = false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...