Выбор отличных записей не в наборе - PullRequest
0 голосов
/ 23 мая 2018

У меня есть таблица клиентов с их опциями контактов с клиентами.

С клиентами можно связаться одним из трех способов:

  • Телефон (1)
  • SMS (2)
  • Электронная почта (3)

идентификатор FK указан в скобках.

Если бы я хотел получить список отдельных идентификаторов клиентов, например, для SMS и электронной почты, я мог бы сделать следующее:

SELECT DISTINCT customer_id 
FROM contact_options 
WHERE contact_option_type_id IN (2,3)

Но как мне сделать обратное?Скажем, я хочу (DISTINCT) список клиентов, у которых нет телефонного контакта.Могу ли я сделать это без использования подзапроса?

Я понимаю, что пример надуманный, на практике у меня очень много разных вариантов контактов (около 80).

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Вы можете использовать not exists:

select distinct c.customer_id
from contact_options c
where not exists (select 1 
                   from contact_options
                   where customer_id = c.customer_id and 
                         contact_option_type_id  = 1
                  );

Я не думаю, что exists имеет проблемы с производительностью, если у вас есть правильная индексация delcared.

0 голосов
/ 23 мая 2018

Один из вариантов - использовать агрегацию:

SELECT customer_id
FROM contact_options
GROUP BY customer_id
HAVING SUM(CASE WHEN contact_option_type_id = 1 THEN 1 ELSE 0 END) = 0;

Мы также можем попробовать сделать это, используя EXISTS:

SELECT DISTINCT customer_id
FROM contact_options c1
WHERE NOT EXISTS (SELECT 1 FROM contact_options c2
    WHERE c1.customer_id = c2.customer_id AND c2.contact_option_type_id = 1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...