SQL:选择客户每天不购买的商品

时间:2019-01-29 18:10:47

标签: mysql sql

我有一张桌子,每天都有一个顾客购买。我正在尝试获取客户每天未购买的所有物品的清单。

更多说明:下表是

+------------+---------+------------+
| dt         | product | product_id |
+------------+---------+------------+
| 2019-01-01 | Milk    |          1 |
| 2019-01-02 | Bread   |          2 |
| 2019-01-03 | Butter  |          3 |
| 2019-01-04 | Beer    |          4 |
| 2019-01-05 | Salt    |          5 |
| 2019-01-06 | Sugar   |          6 |
+------------+---------+------------+

我正在尝试基于整个列表获取未购买商品的报告。

+------------+------------------------------+
| dt         | product_not_purchased        | 
+------------+------------------------------+
| 2019-01-01 | Bread,Butter,Beer,Salt,Sugar |
| 2019-01-02 | Milk,Butter,Beer,Salt,Sugar  |
| 2019-01-03 | Milk,Bread,Beer,Salt,Sugar   |
+------------+------------------------------+

为简单起见,此处的数据仅针对一位客户,并且该客户仅购买一件商品。但是日期不是固定的,日期可能会以不规则的频率持续增长。

一天查询示例:

select dt, product, product_id from
trans  where product_id not in (select distinct product_id
from trans where dt not in ( '2019-01-01'))
where dt = '2019-01-01';

我每天都在尝试扩展它。我尝试使用CTE和分区,但是没有用。 我的另一个解决方案是创建一个临时表并使用减号子句。 我应该如何解决这个问题?还是临时表是最好的解决方案?

SQL查询以创建表并插入值。我正在使用MySQL:

create table trans (dt date, product varchar(10), product_id int);


insert into trans values ('2019-01-01','Milk',1);
insert into trans values ('2019-01-02','Bread',2);
insert into trans values ('2019-01-03','Butter',3);
insert into trans values ('2019-01-04','Beer',4);
insert into trans values ('2019-01-05','Salt',5);
insert into trans values ('2019-01-06','Sugar',6);

2 个答案:

答案 0 :(得分:0)

如果您只有trans表:

select dt, group_concat(product order by product) product_not_purchased from (
  select distinct t.dt, tt.product from trans t
  inner join trans tt
  on tt.dt <> t.dt
) t
group by dt

请参见demo

答案 1 :(得分:0)

使用cross join每天生成所有产品。然后筛选出已购买的商品并汇总其余商品:

select d.dt, group_concat(p.product)
from (select distinct dt from t) d cross join
     (select distinct product from t) p left join
     t
     on t.dt = d.dt and t.product = p.product
where t.product is null
group by d.dte;