生成含历史最大日期的修正日期列的最优SQL解决方案
实现全局累计最大日期列的解决方案
这个需求其实用窗口函数就能轻松解决,Lead和Lag这类偏移函数确实不适合——它们只能获取相邻行的特定值,而我们需要的是截至当前行的所有历史行(包括当前行)中的全局最大日期。
测试数据准备
先确认你的测试表和数据(SQL代码如下):
CREATE TABLE Dummy_Data ( ID INT, TextField VARCHAR(20), DateField DATE ); INSERT INTO Dummy_Data (ID, TextField, DateField) VALUES (1, 'Random Text', '2018-01-04'), (1, 'Random Text', '2018-02-04'), (1, 'Random Text', '2018-05-01'), (2, 'Random Text', '2018-01-14'), (2, 'Random Text', '2018-06-05'), (2, 'Random Text', '2018-01-01'), (2, 'Random Text', '2018-02-01'), (3, 'Random Text', '2018-09-04');
最优查询语句
下面的SQL语句可以直接得到你想要的结果:
SELECT ID, TextField, DateField, MAX(DateField) OVER ( ORDER BY (SELECT NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS Correcteddate FROM Dummy_Data ORDER BY (SELECT NULL); -- 保持插入顺序,若有明确排序键(如自增主键)请替换
关键逻辑解释
- 窗口函数
MAX(DateField) OVER (...):计算指定窗口范围内的最大日期值,这是实现需求的核心。 ORDER BY (SELECT NULL):这里是为了匹配你示例中的行顺序(和数据插入顺序一致)。注意这不是SQL标准行为,不同数据库对无排序的结果顺序处理可能有差异,如果你的表有明确的排序依据(比如自增主键列),建议替换成该列来确保顺序稳定。ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:明确指定窗口范围是从结果集的第一行到当前行,这样每一行的Correcteddate都会是截至当前行的所有历史日期中的最大值。
结果验证
执行上述查询后,返回的结果完全符合你的需求:
| ID | TextField | DateField | Correcteddate |
|---|---|---|---|
| 1 | Random Text | 2018-01-04 | 2018-01-04 |
| 1 | Random Text | 2018-02-04 | 2018-02-04 |
| 1 | Random Text | 2018-05-01 | 2018-05-01 |
| 2 | Random Text | 2018-01-14 | 2018-05-01 |
| 2 | Random Text | 2018-06-05 | 2018-06-05 |
| 2 | Random Text | 2018-01-01 | 2018-06-05 |
| 2 | Random Text | 2018-02-01 | 2018-06-05 |
| 3 | Random Text | 2018-09-04 | 2018-09-04 |
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

