题目:
? ??从订单明细表(order_detail)中查询出所有购买过商品1和商品2,但是没有购买过商品3的用户
订单表 order_info
? ? ? ??
order_id (订单id) | user_id (用户id) | create_date (下单日期) | total_amount (订单金额) |
---|---|---|---|
1 | 101 | 2021-09-30 | 29000.00 |
10 | 103 | 2020-10-02 | 28000.00 |
订单明细表 order_detail
? ? ? ?
order_detail_id(订单明细id) | order_id(订单id) | sku_id(商品id) | create_date(下单日期) | price(商品单价) | sku_num(商品件数) |
---|---|---|---|---|---|
1 | 1 | 1 | 2021-09-30 | 2000.00 | 2 |
2 | 1 | 3 | 2021-09-30 | 5000.00 | 5 |
22 | 10 | 4 | 2020-10-02 | 6000.00 | 1 |
23 | 10 | 5 | 2020-10-02 | 500.00 | 24 |
24 | 10 | 6 | 2020-10-02 | 2000.00 | 5 |
计算逻辑
? ? ?select
? ? ? ? ? ? od.order_id,
? ? ? ? ? ? sku_id,
? ? ? ? ? ? user_id
? ? ?from ?order_detail od
? ? ?join??order_info oi??
? ? ?on oi.order_id = od.order_id? ? ? ? ? ? ? ?t1
? ? ?
? ? select?
? ? ? ? ?user_id,
? ? ? ? ? sku_id,
? ? ? ? ? count(*) ct
? ? from t1
? ? group by user_id,sku_id? ? ? ? ? ? ? ? ? ? t2
? ? select
? ? ? ? ? ? user_id
? ? ?from t2
? ? where sku_id in (1,2) and user_id not in?
? ?(select
? ? ? ? ? ? user_id
? ? from t2
? ? where sku_id = 3)
? ?group by user_id
? ??
? ??
with tmp1 as (
select
sku_id,
user_id,
count(*) ct
from
(
select
od.order_id,
sku_id,
user_id
from
order_detail od
join
order_info oi
on
od.order_id = oi.order_id
)t1
group by sku_id,user_id
)
select
user_id
from
tmp1
where sku_id in (1,2)
and user_id not in
(select
user_id
from tmp1
where sku_id = 3)
group by user_id
? ? ??
order_detail od
join order_info oi on od.order_id = oi.order_id
? ? ?
SELECT
oi.user_id,
od.sku_id
from t1
group by
oi.user_id,
od.sku_id
? ? 不难看出,使用sum if 可以统计购买1,2的用户。若不符合过滤条件,将不会展示用户信息
? ? 同时,having后面直接添加聚合函数进行聚合,简化了在select语句写聚合函数的过程。
SELECT
user_id
from t3
group by
user_id
having
sum(if (sku_id = 3, -3, if (sku_id in (1, 2), 1, 0))) = 2
SELECT
user_id
from
(
SELECT
oi.user_id,
od.sku_id
from
order_detail od
join order_info oi on od.order_id = oi.order_id
group by
oi.user_id,
od.sku_id
) t
group by
user_id
having
sum(if (sku_id = 3, -3, if (sku_id in (1, 2), 1, 0))) = 2
------ 第二种是某位大佬写的,更推荐第二种写法,不禁肃然起敬。