首页 > 解决方案 > 选择仅订购特定会议而不订购其他会议的客户

问题描述

假设我们有一个客户表和一个订单表,它们像这样链接在一起:client.id = order.client_id。订单表条目包含已购买的产品 ID。产品表条目包含购买此产品的会议 ID。
如何从特定会议列表中选择仅购买产品的客户?

我可以用一个 PHP 脚本来解决这个问题,发出多个请求,重新排列数据,但这并不好玩。

到目前为止我试过这个:

select
    o.client_id,
    array_agg(p.conference_id) as conference_ids
from product as p
left join order as o
    on o.id = p.order_id
where
    p.conference_id = any('{ 46545, 46543 }'::int[])

但这并没有奏效,因为它选择的客户不仅来自这些会议,而且还来自其他会议。

编辑:固定 sql 在语法上是正确的

标签: sqlpostgresqlcountrelational-division

解决方案


在不使用数组的情况下解决此问题的一种方法是:

select client.id
from product as p
left join order as o on o.id = p.order_id
group by client.id
having count(*) filter(where p.conference_id not in (46545, 46543)) = 0;

如果您还想断言上述两个会议也都参加了(即都参加了,但没有其他人参加),您可以在该子句中添加另一个断言HAVING

select client.id
from product as p
left join order as o on o.id = p.order_id
group by client.id
having count(*) filter(where p.conference_id not in (46545, 46543)) = 0 and
       min(p.conference_id) <> max(p.conference_id);

推荐阅读