SQL技术问题:按Name分组生成相邻日期起止区间
解决SQL中获取同组下一条记录日期作为结束日期的问题
原表数据
假设你的表名为your_table,数据如下:
Name Date x Jan-01 y Feb-01 z Mar-01 x Jan-02 y Feb-02 z Mar-02 x Jan-03 y Feb-03 z Mar-03 x Jan-04 y Feb-04 z Mar-04 x Jan-05 y Feb-05 z Mar-05
最优解决方案:使用窗口函数LEAD()
这是最简洁高效的方法,几乎所有现代SQL数据库(MySQL 8.0+、PostgreSQL、SQL Server、Oracle等)都支持窗口函数:
SELECT Name, Date AS DateStart, LEAD(Date) OVER (PARTITION BY Name ORDER BY Date) AS DateEnd FROM your_table ORDER BY Date, Name;
代码解释:
PARTITION BY Name:将数据按Name分组,确保只在同一个用户的记录范围内查找下一条日期ORDER BY Date:每组内按Date排序,保证LEAD()能获取到正确的"下一条"日期LEAD(Date):获取当前行所在分组中,下一行的Date值;如果当前行是分组内最后一条记录,则返回NULL
执行后就能得到你期望的结果:
Name DateStart DateEnd x Jan-01 Jan-02 y Feb-01 Feb-02 z Mar-01 Mar-02 x Jan-03 Jan-04 y Feb-03 Feb-04 z Mar-03 Mar-04 x Jan-05 NULL y Feb-05 NULL z Mar-05 NULL
兼容老版本SQL的方案:自关联查询
如果你的数据库不支持窗口函数(比如MySQL 5.x及更早版本),可以用自关联的方式实现:
SELECT t1.Name, t1.Date AS DateStart, MIN(t2.Date) AS DateEnd FROM your_table t1 LEFT JOIN your_table t2 ON t1.Name = t2.Name AND t2.Date > t1.Date GROUP BY t1.Name, t1.Date ORDER BY t1.Date, t1.Name;
代码解释:
- 左连接同
Name且日期大于当前行的记录 - 用
MIN(t2.Date)取这些记录中最小的日期,也就是当前行的"下一条"日期 - 如果没有符合条件的
t2记录,MIN(t2.Date)会返回NULL
内容的提问来源于stack exchange,提问作者Gys---p
相关产品推荐
相关产品推荐

