SELECT user_id, item_id, IF(SUM(is_buy)>0,1,0) AS '已购买', IF(SUM(is_buy)>0 AND SUM(is_favor)=0,1,0) AS '购买未收藏', IF(SUM(is_buy)=0 AND SUM(is_favor)>0,1,0) AS '收藏未购买', IF(SUM(is_buy)>0 AND SUM(is_favor)>0,1,0) AS '收藏且购买' FROM ( #is_buy中1代表已购买,0代表未购买,is_favor中1代表收藏了,0代表未收藏 SELECT user_id,item_id,1 AS is_buy,0 AS is_favor FROM orders UNION SELECT user_id,item_id,0 AS is_buy,1 AS is_favor FROM favorites ) AS t GROUP BY user_id,item_id ORDER BY user_id,item_id
SELECT user_id, item_id, IF(MIN(status) = 1, 1, 0) AS “已购买”, IF(MAX(status) = 1, 1, 0) AS “购买未收藏”, IF(MIN(status) = 2, 1, 0) AS “收藏未购买”, IF(COUNT(DISTINCT status) =2, 1, 0) AS “收藏且购买” FROM (SELECT user_id, item_id, 1 AS status FROM orders UNION ALL SELECT user_id, item_id, 2 AS status FROM favorites) t GROUP BY user_id, item_id ORDER BY user_id, item_id
Oracle支持full join,mysql是不支持full join的,等价于左外连接+ union+右外连接实现
# 创建表&插入数据 CREATE TABLE `orders` ( `id` int(11) NOT NULL, `user_id` char(11) NOT NULL, `item_id` int(11) NOT NULL, `pay_time` date NOT NULL, `item_num` int(11) NOT NULL, PRIMARY KEY (`id`,`user_id`,`item_id`)); INSERT INTO orders VALUES(1,'001',201,'2018-08-31',1); INSERT INTO orders VALUES(2,'002',203,'1987-06-26',2); INSERT INTO orders VALUES(3,'003',203,'1996-08-03',1); INSERT INTO orders VALUES(4,'003',203,'1997-08-03',1); CREATE TABLE `favorites` ( `id` int(11) NOT NULL, `user_id` char(11) NOT NULL, `item_id` int(11) NOT NULL, `fav_time` date NOT NULL, PRIMARY KEY (`id`,`user_id`,`item_id`)); INSERT INTO favorites VALUES(1,'001',201,'2018-08-31'); INSERT INTO favorites VALUES(2,'002',202,'1987-06-26'); INSERT INTO favorites VALUES(3,'003',204,'1996-08-03'); # MySQL不支持 SELECT o.user_id, o.item_id, (CASE when o.pay_time is not null then 1 else 0 end) as '已购买', (CASE when o.pay_time is not null and f.fav_time is null then 1 else 0 end) as '购买未收藏', (CASE when o.pay_time is null and f.fav_time is not null then 1 else 0 end) as '收藏未购买', (CASE when o.pay_time is not null and f.fav_time is not null then 1 else 0 end) as '收藏且购买' FROM orders o FULL OUTER JOIN favorites f ON o.user_id = f.user_id AND o.item_id = f.item_id; # MySQL应该这么写 SELECT o.user_id,o.item_id, (CASE when o.pay_time is not null then 1 else 0 end) as '已购买', (CASE when o.pay_time is not null and f.fav_time is null then 1 else 0 end) as '购买未收藏', (CASE when o.pay_time is null and f.fav_time is not null then 1 else 0 end) as '收藏未购买', (CASE when o.pay_time is not null and f.fav_time is not null then 1 else 0 end) as '收藏且购买' FROM orders o LEFT JOIN favorites f ON o.user_id = f.user_id AND o.item_id = f.item_id UNION SELECT f.user_id,f.item_id, (CASE when o.pay_time is not null then 1 else 0 end) as '已购买', (CASE when o.pay_time is not null and f.fav_time is null then 1 else 0 end) as '购买未收藏', (CASE when o.pay_time is null and f.fav_time is not null then 1 else 0 end) as '收藏未购买', (CASE when o.pay_time is not null and f.fav_time is not null then 1 else 0 end) as '收藏且购买' FROM orders o RIGHT JOIN favorites f ON o.user_id = f.user_id AND o.item_id = f.item_id ORDER BY user_id, item_id;
先以orders表为主表left join 连接两表,再以favorites表为主表right join 连接两表,最后union 去除重复行并合并。
select o.user_id,o.item_id, case when o.pay_time is not null then 1 else 0 end as "已购买", case when o.pay_time is not null and f.fav_time is null then 1 else 0 end as "购买未收藏", case when o.pay_time is null and f.fav_time is not null then 1 else 0 end as "收藏未购买", case when o.pay_time is not null and f.fav_time is not null then 1 else 0 end as "收藏且购买" from orders o left join favorites f on o.user_id=f.user_id,o.item_id=f.item_id union select f.user_id,f.item_id, case when o.pay_time is not null then 1 else 0 end as "已购买", case when o.pay_time is not null and f.fav_time is null then 1 else 0 end as "购买未收藏", case when o.pay_time is null and f.fav_time is not null then 1 else 0 end as "收藏未购买", case when o.pay_time is not null and f.fav_time is not null then 1 else 0 end as "收藏且购买" from orders o right join favorites f on o.user_id=f.user_id,o.item_id=f.item_id order by user_id,item_id;
SELECT o.user_id, o.item_id, case when o.pay_time is not Null then 1 else 0 end as "已购买", case when o.pay_time is not NUll and f.fav_time is Null then 1 else 0 end as "购买未收藏", case when o.pay_time is Null and f.fav_time is not Null then 1 else 0 end as "收藏未购买", case when o.pay_time is not Null and f.fav_time is not Null then 1 else 0 end as "收藏且购买" from orders o left join favorites f on o.user_id = f.user_id and o.item_id = f.item_id UNION SELECT f.user_id, f.item_id, case when o.pay_time is not Null then 1 else 0 end as "已购买", case when o.pay_time is not NUll and f.fav_time is Null then 1 else 0 end as "购买未收藏", case when o.pay_time is Null and f.fav_time is not Null then 1 else 0 end as "收藏未购买", case when o.pay_time is not Null and f.fav_time is not Null then 1 else 0 end as "收藏且购买" from orders o right join favorites f on o.user_id = f.user_id and o.item_id = f.item_id order by user_id, item_id;商户和物品是联合主键,左右连接分别统计两张表里的情况,最后union去重,排序
不是所有购买的商品都被收藏,所以我们先以左边的order表为主表外关联右表。如果右表记录为空,说明这些items没有被收藏,即购买未收藏
# 计算第一部分 (select o.user_id, o.item_id, if(count(o.item_id)>0,1,0) as "已购买", case when count(o.item_id)>0 and count(f.item_id)=0 then 1 else 0 end as "购买未收藏", case when count(o.item_id)=0 and count(f.item_id)>0 then 1 else 0 end as "收藏未购买", case when count(o.item_id)>0 and count(f.item_id)>0 then 1 else 0 end as "购买且收藏" from orders o left join favorites f on o.user_id = f.user_id and o.item_id = f.item_id group by o.user_id,o.item_id order by o.user_id,o.item_id) # union 去重 union # 计算第二部分 (select f.user_id, f.item_id, if(count(o.item_id)>0,1,0) as "已购买", case when count(o.item_id)>0 and count(f.item_id)=0 then 1 else 0 end as "购买未收藏", case when count(o.item_id)=0 and count(f.item_id)>0 then 1 else 0 end as "收藏未购买", case when count(o.item_id)>0 and count(f.item_id)>0 then 1 else 0 end as "购买且收藏" from favorites f left join orders o on f.user_id = o.user_id and f.item_id = o.item_id group by f.user_id,f.item_id order by f.user_id,f.item_id);
最终结果:
select ab.user_id,ab.item_id,
(case when ab.pay_time is not null then 1 else 0 end) as '已购买',
(case when ab.pay_time is not null and ab.fav_time is null then 1 else 0 end) as '购买未收藏',
(case when ab.pay_time is null and ab.fav_time is not null then 1 else 0 end) as '收藏未购买',
(case when ab.pay_time is not null and ab.fav_time is not null then 1 else 0 end) as '收藏且购买'
from
(select *
from orders as a
full join favorites as b
on a.user_id=b.user_id) as ab
group by ab.user_id,order by ab.item_id;
select ab.user_id,ab.item_id, (case when ab.pay_time is not null then 1 else 0 end) as '已购买', (case when ab.pay_time is not null and ab.fav_time is null then 1 else 0 end) as '购买未收藏', (case when ab.pay_time is null and ab.fav_time is not null then 1 else 0 end) as '收藏未购买', (case when ab.pay_time is not null and ab.fav_time is not null then 1 else 0 end) as '收藏且购买' from (select * from orders as a full join favorites as b on a.user_id=b.user_id) as ab group by ab.user_id,order by ab.item_id;
select select distinct a.user_id,a.item_id ,case when pay_time is not null then 1 else 0 end as 已购买 ,case when pay_time is not null and fav_time is null then 1 else 0 end as 购买未收藏 ,case when pay_time is null and fav_time is not null then 1 else 0 end as 收藏未购买 ,case when pay_time is not null and fav_time is not null then 1 else 0 end as 收藏且购买 from ( select user_id,item_id from orders union (select user_id,item_id from favorites) )a left join orders as o on a.user_id=o.user_id and a.item_id=o.item_id left join favorites as f on a.user_id=f.user_id and a.item_id=f.item_id order by user_id;
SELECT o.user_id,o.item_id, (CASE WHEN pay_time IS NOT NULL THEN 1 ELSE 0 END) AS 'buy', (CASE WHEN fav_time IS NULL THEN 1 ELSE 0 END) AS 'Nofavbuy', 0 as 'favNobuy', (CASE WHEN fav_time IS NOT NULL THEN 1 ELSE 0 END) AS 'favbuy' FROM orders o LEFT JOIN favorites f ON o.user_id = f.user_id and o.item_id = f.item_id UNION SELECT f.user_id,f.item_id, (CASE WHEN pay_time IS NOT NULL THEN 1 ELSE 0 END) AS 'buy', 0 as 'Nofavbuy', (CASE WHEN pay_time IS NULL THEN 1 ELSE 0 END) AS 'favNobuy', (CASE WHEN pay_time IS NOT NULL THEN 1 ELSE 0 END) AS 'favbuy' FROM favorites f LEFT JOIN orders o ON f.user_id = o.user_id and f.item_id = o.item_id ORDER BY user_id,item_id;
SELECT a.user_id,a.item_id, if(b.user_id is not null,1,0) 已购买, if(b.user_id is not null and c.user_id is null,1,0) 购买未收藏, if(b.user_id is null and c.user_id is not null,1,0) 收藏未购买, if(b.user_id is not null and c.user_id is not null,1,0) 收藏且购买 FROM ( SELECT user_id,item_id FROM orders UNION SELECT user_id,item_id FROM favorites ) a LEFT JOIN orders ON a.user_id = b.user_id AND a.item_id=b.item_id LEFT JOIN favorites b ON a.user_id = c.user_id AND a.item_id = c.item_id