sql- sum if() 用法举例

题目:

从订单明细表(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

计算逻辑

1.使用差集

1. 将订单表与订单明细表进行join,获取所有用户,商品信息
sql 复制代码
     select

            od.order_id,

            sku_id,

            user_id

     from  order_detail od

     join  order_info oi  

     on oi.order_id = od.order_id               t1
2.按照用户,商品,分组,统计用户购买单种商品的数量
sql 复制代码
    select 

         user_id,

          sku_id,

          count(*) ct

    from t1

    group by user_id,sku_id                    t2
3.根据用户购买每种商品的数量,筛选购买1,2但是没有购买3的商品。
sql 复制代码
    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

    
4.拼接最终SQL
sql 复制代码
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

2.使用sum if

1. 将订单表与订单明细表进行join,获取所有用户,商品信息
sql 复制代码
order_detail od
      join order_info oi on od.order_id = oi.order_id
2.按照用户,商品,分组,统计用户-商品的信息
sql 复制代码
    SELECT
      oi.user_id,
      od.sku_id
    from t1
    group by
      oi.user_id,
      od.sku_id
3.根据用户分组,使用sum..if.. 统计购买1,2但是没有购买3的用户。

不难看出,使用sum if 可以统计购买1,2的用户。若不符合过滤条件,将不会展示用户信息

同时,having后面直接添加聚合函数进行聚合,简化了在select语句写聚合函数的过程。

sql 复制代码
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
4.最终SQL
sql 复制代码
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

------ 第二种是某位大佬写的,更推荐第二种写法,不禁肃然起敬。

相关推荐
梦想的旅途218 分钟前
企业微信Webhook回调怎么做自动回复和AI客服
数据库·机器人·自动化·企业微信·rpa
Zguigo32 分钟前
OCR 核心原理 + 模型 + 检测与识别
数据库·ocr
凤山老林34 分钟前
零停机数据库演进:Spring Boot 集成 Flyway 与平滑DDL变更策略
数据库·spring boot·后端
曹牧1 小时前
Oracle:取固定分隔符字符串中第一个元素
数据库·oracle
szarron1 小时前
VNA6 便携式矢量网络分析仪:从入门到精通
数据库·嵌入式硬件·测试工具·5g·射频工程
临床数据科学和人工智能兴趣组2 小时前
R语言中,列表是一种非常灵活的数据结构,它可以存储不同类型的对象,如向量、矩阵、数据框、甚至其他列表
数据结构·数据库·r语言·r语言-4.2.1·临床试验
cmes_love2 小时前
期货五档Level2行情数据和分钟历史行情数据下载分析
数据库
某不知名網友2 小时前
MySQL数据库库级操作|创建、字符集、修改删除、备份恢复
数据库·mysql
zone_z3 小时前
Oracle 数据库基础故障排查系列(12 篇)
数据库·oracle·dba·troubleshooting·blog-series
DBA_G3 小时前
GBase 8a数据库RANGE分区操作详细解读
数据库·oracle