MySQL背后的故事(三)

最近刷SQL题,发现好多有点难度的题都是围绕着分组的组内排名来出题的。
这里记录一下聚合函数的一个隐藏的用法
题目:
在这里插入图片描述请你写出一个sql语句查询在2025-10-15以后,如果有一个用户下单2个以及2个以上状态为购买成功的C++课程或Java课程或Python课程,那么输出这个用户的user_id,以及满足前面条件的第一次购买成功的C++课程或Java课程或Python课程的日期first_buy_date,以及满足前面条件的第二次购买成功的C++课程或Java课程或Python课程的日期second_buy_date,以及购买成功的C++课程或Java课程或Python课程的次数cnt,并且输出结果按照user_id升序排序,以上例子查询结果如下:
在这里插入图片描述

本题要求获取每个分组内的第一名和第二名的数据。
而我们都知道,一般情况下,group by以后都是默认取组内第一条记录的,那么我们要获取组内的多个满足条件的记录需要怎么做呢?
具体见下面代码中的min()函数:

select user_id
      ,min(case when r = 1 then date end) as first_buy_date
      ,min(case when r = 2 then date end) as second_buy_date
      ,count(1)                           as cnt
from ( 
    select *
          ,rank() over(partition by user_id order by date) as r
    from order_info
    where 1=1
    and status = 'completed'
    and date > '2025-10-15'
    and product_name in ('C++', 'Python', 'Java'))t
group by user_id
having count(1) >= 2

min(case when r = 1 then date end)这里如果不加min函数,那么操作对象就是group by取出的默认第一条记录,不符合when r=1这个条件的话就返回null,而加上聚合函数min()的话,case when操作就是面向所有当前组组内的记录了,所以一定能找出r=1的记录的。
理解了这个的话,那么我们可以知道,把min()换成其他的聚合函数也是OK的。
总结:聚合函数的处理对象是当前组组内的记录,利用这个便利,我们可以按照题目要求在聚合函数内部对组内的记录进行筛选。以后类似的求组内的记录可以考虑用这个思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值