Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 寻找只购买别人没有购买的物品的客户_Sql_Postgresql - Fatal编程技术网

Sql 寻找只购买别人没有购买的物品的客户

Sql 寻找只购买别人没有购买的物品的客户,sql,postgresql,Sql,Postgresql,下面是订单列表,有没有办法找到只购买了其他人没有购买的产品的客户的身份证 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

下面是订单列表,有没有办法找到只购买了其他人没有购买的产品的客户的身份证

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         |

我是否必须找到所有购买其他人没有购买的物品的人,并创建一个不包括这些人的表?

您希望该人购买的所有产品都是唯一的

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;

唉,Postgres不支持COUNTDISTINCT作为窗口函数。

这是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

正在联接的内联视图将获取只有一个person_id的所有product_id。一旦找到所有product_id,它们将联接到原始customers表以获取person_id。这应该能解决你的问题

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;

传统的布尔聚合自连接

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

下面是另一个解决方案:

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)

首先,找到单个订单中出现的所有产品的标识符。然后,我们从订单中的所有人员中减去那些没有单一产品订单的人员,即至少订购了其他人订购的产品的所有人员。

如果数据库是mysql怎么办?@Teja。这个问题被标记为Postgres。如果你有一个关于MySQL的问题,那就作为一个新问题来问吧。一个人能买两次同样的产品吗?我更喜欢这个解决方案。我不知道布卢和。
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)