В поиск не попадают значения, при соблюдении условий. Выведите список клиентов у которых ВСЕ тикеты закрыты (status = 0)

ticket_id custumer_id status open close 1 1 1 01.01.2015
2 1 0 01.01.2015 10.01.2015 4 1 0 02.01.2015 10.01.2015 11 1 1 09.01.2015
12 1 0 10.01.2015 18.01.2015 14 1 1 12.01.2015
5 2 0 03.01.2015 11.01.2015 6 2 0 04.01.2015 12.01.2015 7 2 0 05.01.2015
15 2 0 13.01.2015 16.01.2015 16 2 0 14.01.2015 17.01.2015 8 3 1 06.01.2015
9 3 0 07.01.2015 12.01.2015 10 3 0 08.01.2015 16.01.2015 3 4 1 01.01.2015
13 4 0 11.01.2015 18.01.2015 18 5 1 16.01.2015
17 6 0 15.01.2015 18.01.2015

введите сюда описание изображения

Есть база данных. Задание: Выведите список клиентов у которых ВСЕ тикеты закрыты (status = 0)

Проблема: я не в совершенстве знаю SQL, мой запрос с select distinct customer_id from ticket where status=0 and close_dt is not null не подходит правильный ответ customer_id=6. Как мне написать запрос, что если например у customer_id=1 есть незакрытый тикет, то как его убрать из базы данных поиски и он не попадал в выборку, где у него есть закрытые тикеты.


Ответы (2 шт):

Автор решения: Vitalizzare

Можно сгруппировать данные по идентификатору клиента и проверить, чтобы максимальный статус тикета в группе был равен нулю:

SELECT 
  customer_id 
FROM 
  ticket
GROUP BY 
  customer_id 
HAVING
  MAX(status) = 0;
→ Ссылка
Автор решения: Мелкий

IRL будет предпочтительнее

select ...
from customer
where not exists(
    select from ticket t
    where t.customer_id = customer.id
        and status != 0
);

потому что

  • вам определённо понадобится вывести дополнительные данные клиента, а не только id
  • запрос получится ускорить созданием индекса create index concurrently on ticket (customer_id) where status != 0 чтобы избежать чтение и группировку всей таблицы ticket. Разумно ожидать по предметной области, что большинство тикетов будут закрыты.

Есть отличие в обработке клиентов, у которых вовсе нет ни одного тикета - должны ли они быть в списке. Это вопрос к задаче.

→ Ссылка