SQL:select 所有商品已过期的所有客户

SQL: select all customers that have all items expired

考虑以下数据库结构

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

我需要 select 所有客户,他们的所有物品都已过期。这是我目前所拥有的

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 子句中添加一些内容,但我没有每个客户的确切项目数。

您确实可以使用 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 并不能顺利进行(尽管 MySQL 的旧版本默认允许这样做)。您应该在 select 子句中枚举要保留的列 group by 子句中的

您可以简化查询,因为您不需要 customer table。然后我会去:

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;