如何在SQL中按客户分组并依据退保日期进行倒序排名?
实现分组内基于日期的降序排名
没问题!这个需求是典型的分组内按日期倒序排名场景,用SQL的窗口函数就能轻松搞定,下面分不同数据库场景给你具体实现方法:
主流数据库通用写法(支持窗口函数)
如果你的数据库是MySQL 8.0+、PostgreSQL、SQL Server、Oracle这类支持窗口函数的版本,直接用RANK()窗口函数就能实现:
SELECT product, customer, surrender_date, -- 按customer分组,组内按surrender_date从新到旧排序后生成排名 RANK() OVER (PARTITION BY customer ORDER BY surrender_date DESC) AS rank FROM your_table_name; -- 替换成你的表名
关键参数说明:
PARTITION BY customer:将数据按customer字段拆分,每个customer单独计算排名ORDER BY surrender_date DESC:在每个分组内,按surrender_date从最新日期到最旧日期排序RANK():生成排名(如果有相同日期的记录,会出现并列排名,比如两条最新日期的记录都排1,下一条直接排3);如果需要连续无并列的排名,可以替换成ROW_NUMBER()
MySQL 5.x 兼容写法(无窗口函数)
如果你的MySQL版本低于8.0,不支持窗口函数,可以用子查询的方式实现:
SELECT t1.product, t1.customer, t1.surrender_date, -- 统计同customer下日期比当前记录新的数量,加1就是当前记录的排名 (SELECT COUNT(*) FROM your_table_name t2 WHERE t2.customer = t1.customer AND t2.surrender_date > t1.surrender_date) + 1 AS rank FROM your_table_name t1 ORDER BY t1.customer, t1.rank;
逻辑说明:
对于每条记录,我们统计同一个customer中,surrender_date比它更晚(更新)的记录总数,加1之后就是它的排名——最新的日期没有比它更晚的记录,所以排名是1,完全符合你的需求。
执行以上任意一种写法,都能得到你期望的结果:
| product | customer | surrender_date | rank |
|---|---|---|---|
| A | a | 2020/5/1 | 2 |
| B | a | 2020/6/1 | 1 |
| C | b | 2019/7/1 | 3 |
| D | b | 2020/8/1 | 2 |
| E | b | 2020/9/1 | 1 |
内容的提问来源于stack exchange,提问作者Heisenberg
相关产品推荐
相关产品推荐

