【发布时间】:2021-08-27 03:31:30
【问题描述】:
在 SQL Server 中对时间序列使用 lag 函数时,我总是与时间序列中的 first 值作斗争。 假设这个简单的例子
CREATE TABLE demo
([id] int, [time] date, [content] int)
;
INSERT INTO demo (id, time, content) VALUES
(1, '2021-05-31', cast(rand()*1000 as int)),
(2, '2021-06-01', cast(rand()*1000 as int)),
(3, '2021-06-02',cast(rand()*1000 as int)),
(4, '2021-06-03', cast(rand()*1000 as int)),
(5, '2021-06-04', cast(rand()*1000 as int)),
(6, '2021-06-05', cast(rand()*1000 as int)),
(7, '2021-06-06', cast(rand()*1000 as int)),
(8, '2021-06-07', cast(rand()*1000 as int)),
(9, '2021-06-08', cast(rand()*1000 as int));
我想在六月获取所有值及其之前的值,所以像这样
select content, lag(content, 1, null) over (order by time)
from demo
where time >= '2021-06-01'
到目前为止一切都很好,但是,第一个条目将导致前一个值的 null。
当然有很多关于如何填充空值的解决方案,例如子选择更大的范围等,但对于非常大的表,我不知何故认为应该有一个优雅的解决方案。
有时我会做这样的事情
select content, lag(content, 1,
(select content from demo d1 join
(select max(time) maxtime from demo where time < '2021-06-01') d2 on d1.time = d2.maxtime
)) over (order by time)
from demo
where time >= '2021-06-01'
有没有更有效的方法? (注意:当然对于这个简单的例子我没有什么不同,但是对于具有分区和 500'000'000 个条目的表,应该找到最有效的解决方案)
查看fiddle
【问题讨论】:
-
那么你想为第一个值显示什么值?
-
第一行的日期为2021-06-01,前一个值为2021-5-31,内容为1,所以为1
标签: sql sql-server tsql lag