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

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

相关推荐
陌上丨4 小时前
Redis的Key和Value的设计原则有哪些?
数据库·redis·缓存
AI_56784 小时前
AWS EC2新手入门:6步带你从零启动实例
大数据·数据库·人工智能·机器学习·aws
ccecw5 小时前
Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错
数据库·mysql
JH30735 小时前
达梦数据库与MySQL的核心差异解析:从特性到实践
数据库·mysql
数据知道5 小时前
PostgreSQL 核心原理:如何利用多核 CPU 加速大数据量扫描(并行查询)
数据库·postgresql
麦聪聊数据6 小时前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务6 小时前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
Goat恶霸詹姆斯8 小时前
mysql常用语句
数据库·mysql·oracle
大模型玩家七七8 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
曾经的三心草8 小时前
redis-9-哨兵
数据库·redis·bootstrap