有多少客户在与产品 B 相同的订单中购买了产品 A

How many customers bought a product A in the same order as product B

我有一个 table daily_orders,我想在其中找到以与手机 phone 相同的订单购买手机壳的客户。 这是table结构

CREATE TABLE daily_orders (
  Order_date datetime,
  orderid varchar(20) NOT NULL,
  CustomerID int NOT NULL,
  Product varchar(20) ,
  Product_Category text,
  Units int
);
-- insert some values
INSERT INTO daily_orders VALUES ('2021-06-15 20:06:31','AABS123',46162,'sku1223','mobile phone',1);
INSERT INTO daily_orders VALUES ('2021-07-01 13:21:22','AABWA23',87949,'sku213','laptops',1);
INSERT INTO daily_orders VALUES ('2021-06-11 07:01:25','AA12WA13',122123,'sku1223','mobile phone',1);
INSERT INTO daily_orders VALUES ('2021-06-11 07:01:25','AA12WA13',122123,'sku1223','mobile covers',2);

输出应该是

CustomerID 
122123

我试过的查询

select a.customerID
from daily_orders a
inner join daily_orders b on a.CustomerID = b.CustomerID
where a.OrderID = b.OrderID and a.CustomerID = b.CustomerID

但是我没有得到想要的输出。 任何建议都会有所帮助。

您可以将 table 与自身合并(一个用于封面,另一个用于手机)以获得您想要的结果。例如:

select c.CustomerId
from daily_orders c
join daily_orders p on p.orderid = c.orderid
where c.Product_Category = 'mobile covers'
  and p.Product_Category = 'mobile phone'

另一种选择是使用 string_agg

select t.customerid
from   ( select d.customerid,
                string_agg(convert(varchar(100), d.Product_Category), ',') cat
         from   daily_orders d
         group by d.customerid
       ) t  
where  t.cat = 'mobile phone,mobile covers'

DBFiddle这里

这是一个“does something exist”查询,最好使用 exists.

来实现

另请注意,Text 数据类型早已被弃用,不应再使用,始终指定 varchar(n)

select o.CustomerID 
from daily_orders o
where Product_Category = 'mobile phone'
and exists (
  select * from daily_orders o2 
    where o2.orderid = o.orderid 
      and o2.Product_Category = 'mobile covers'
);

假设 orderidProduct_Category 的数据类型是 VARCHAR 而不是 TEXT 并且不存在每个 CustomerID 不同的情况orderid,首先过滤 table 以仅获取购买了 'mobile covers' and/or 'mobile phone' 的客户,然后使用聚合仅获取同时购买两者的客户订单:

SELECT DISTINCT CustomerID 
FROM daily_orders 
WHERE Product_Category IN ('mobile covers', 'mobile phone')
GROUP BY CustomerID, orderid 
HAVING COUNT(DISTINCT Product_Category) = 2;

INTERSECT:

SELECT DISTINCT CustomerID
FROM (
  SELECT CustomerID, orderid FROM daily_orders WHERE Product_Category = 'mobile covers'
  INTERSECT
  SELECT CustomerID, orderid FROM daily_orders WHERE Product_Category = 'mobile phone'
) t  

参见demo

如果将数据类型从 text 更改为 varchar,则以下查询应该有效

Table Definition

CREATE TABLE daily_orders (
  Order_date datetime,
  orderid varchar(20) NOT NULL,
  CustomerID int NOT NULL,
  Product varchar(20),
  Product_Category varchar(20),
  Units int
);

Solution

SELECT dor1.customerid,
       dor1.product_category,
       dor2.product_category
FROM   daily_orders dor1
       inner join daily_orders dor2
               ON dor1.customerid = dor2.customerid
                  AND dor1.orderid = dor2.orderid
WHERE  dor1.product_category <> dor2.product_category
       AND dor1.product_category = 'mobile phone'
       AND dor2.product_category = 'mobile covers';