以下是订单列表,有没有办法找到person_id
客户,仅购买的产品没有其他人购买?
CREATE TABLE orders
AS
SELECT product_id, person_id
FROM ( VALUES
( 1 , 1 ),
( 2 , 1 ),
( 2 , 2 ),
( 3 , 3 ),
( 12, 6 ),
( 10, 3 )
) AS t(product_id, person_id);
结果如下表所示:
| person_id |
|-----------|
| 3 |
| 6 |
我是否必须找到所有买过没有其他人买过的物品的人,并创建一个不包括那些人的桌子?
答案 0 :(得分:2)
您希望此人购买的所有产品都是唯一的。
select person_id
from (select t.*,
min(person_id) over (partition by product_id) as minp,
max(person_id) over (partition by product_id) as maxp
from t
) t
group by person_id
having sum(case when minp <> maxp then 1 else 0 end) = 0;
你可能在想&#34;嗯?这是做什么的?&#34;。
子查询计算每个产品的最小人数和最大人数。如果这些是相同的,那么一个人是唯一的购买者。
having
然后检查某个人没有非单一购买者产品。
也许更直观的逻辑措辞是:
select person_id
from (select t.*,
count(distinct person_id) over (partition by product_id) as numpersons
from t
) t
group by person_id
having max(numperson) = 1;
唉,Postgres并不支持COUNT(DISTINCT)
作为窗口功能。
答案 1 :(得分:2)
传统的自我联接与布尔聚合
select o0.person_id
from
orders o0
left join
orders o1 on o0.product_id = o1.product_id and o0.person_id <> o1.person_id
group by o0.person_id
having bool_and(o1.product_id is null)
;
person_id
-----------
3
6
答案 2 :(得分:0)
这是Gordon仅使用聚合的逻辑:
SELECT person_id
FROM
(
SELECT product_id,
-- if count = 1 it's the only customer who bought this product
min(person_id) as person_id,
-- if the combination(person_id,product_id) is unique DISTINCT can be removed
count(distinct person_id) as cnt
FROM customers
GROUP BY product_id
) AS dt
GROUP BY person_id
HAVING max(cnt) = 1 -- only unique products
答案 3 :(得分:0)
正在连接的内联视图获取只有一个person_id的所有product_id。找到所有product_id后,它们将加入原始customers表以获取person_ids。这应该可以解决你的问题!!
SELECT person_id
FROM customers c1
INNER JOIN
(
SELECT product_id
FROM customers
GROUP BY product_id
HAVING COUNT(person_id ) = 1
) c2
ON c1.product_id = c2.product_id;
答案 4 :(得分:0)
这是另一种解决方案:
with unique_products as
(select product_id
from orders
group by product_id
having count(*) = 1)
select person_id
from orders
except
select person_id
from orders
where not exists
(select * from unique_products where unique_products.product_id = orders.product_id)
首先找到单个订单中出现的所有产品标识符。然后我们从所有人(在订单中)减去没有订单的产品(即所有至少订购了其他人订购的产品的人)。