SQL: выберите всех клиентов, у которых истек срок действия всех товаров - PullRequest
1 голос
/ 21 февраля 2020

Рассмотрим следующую структуру БД

customer (id)
invoice (id, customer_id)
invoice_item (id, invoice_id, warranty_expiry)

Мне нужно выбрать всех клиентов, у которых истек срок действия всех их товаров. Вот что у меня есть

select * from customer c
inner join invoice i on c.id = i.customer_id
inner join invoice_item ii on i.id = ii.invoice_id
where ii.warranty_expiry < NOW()
group by c.id
having COUNT(ii.id) // <--- 

Такое ощущение, что я должен что-то добавить в предложение HAVING, но у меня нет точного количества элементов для каждого клиента.

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Вы можете упростить запрос, потому что вам не нужна таблица customer. Тогда я бы go для:

select i.customer_id
from invoice i join
     invoice_item ii
     on i.id = ii.invoice_id
group by i.customer_id
having max(ii.waranty_expiry) < now();

Это предполагает, что warnty_expiry не null. Если это возможно, то:

having max(ii.waranty_expiry) < now() and sum(ii.waranty_expiry is null) = 0;
1 голос
/ 21 февраля 2020

Вы действительно можете использовать предложение having, чтобы убедиться, что у данного клиента истек срок действия всех его товаров. Это работает путем перемещения проверки warranty_expiry из предложения where в предложение having следующим образом:

select c.id
from customer c
inner join invoice i on c.id = i.customer_id
inner join invoice_item ii on i.id = ii.invoice_id
group by c.id
having max(ii.warranty_expiry >= NOW()) = 0

Обратите внимание, что select * и group by не go вдоль хорошо (хотя более старые версии MySQL разрешают это по умолчанию). Вы должны перечислить столбцы, которые вы хотите сохранить в предложении select и в предложении group by.

...