SQL Server Lag 函数添加范围
Posted
技术标签:
【中文标题】SQL Server Lag 函数添加范围【英文标题】:SQL Server Lag function adding range 【发布时间】:2016-12-17 14:33:21 【问题描述】:您好,我是 SQL 的新手,希望有人能在这件事上帮助我。我一直在这里和那里使用滞后函数,但想知道是否有办法重写它以使其成为一个总和范围。因此,我想取前 12 个月,而不是前一个月,并将每个时期的它们加在一起。我不想写 12 行延迟,但想知道是否有办法用更少的代码行来获得它。注意会有空值,如果 12 条记录之一为空,那么它应该为空。
我知道您可以编写子查询来执行此操作,但想知道这是否可能。任何帮助将非常感激。
【问题讨论】:
你可能想要一个 sum() over (partition by left(period,4) order by period) 您使用的是哪个版本的Sql Server
?
您是否每个月都必须有一行,或者您可能缺少行?
【参考方案1】:
您想要窗口函数的“窗口框架”部分。 12 个月的移动平均值如下所示:
select t.*,
sum(balance) over (order by period rows between 11 preceding and current row) as moving_sum_12
from t;
您可以在documentation 中查看窗口框架。
如果你想要一个累积和,你可以完全省略窗框。
我应该注意,您也可以使用lag()
执行此操作,但要复杂得多:
select t.*,
(balance +
lag(balance, 1, 0) over (order by period) +
lag(balance, 2, 0) over (order by period) +
. . .
lag(balance, 11, 0) over (order by period) +
) as sum_1112
from t;
这使用了lag()
的鲜为人知的第三个参数,这是记录不可用时使用的默认值。它替换了coalesce()
。
编辑:
如果你想要NULL
,如果12个值不可用,那么同时使用case
和count()
:
select t.*,
(case when count(*) over (order by period rows between 11 preceding and current row) = 12
then sum(balance) over (order by period rows between 11 preceding and current row)
end) as moving_sum_12
from t;
【讨论】:
但是如果其中一行为空怎么办?我认为您的方法会跳过并采用下一个非空值。我希望它包含 null 并且结果集将为 null,因为您实际上并没有 12 个月的数据。 它会忽略这个值。 应该是count(balance)
而不是count(*)
@DuduMarkovitz 。 . .是的,这是真的。谢谢你。关键是要找到其中包含 NULL
值的行,而不是丢失的行。以上是关于SQL Server Lag 函数添加范围的主要内容,如果未能解决你的问题,请参考以下文章
sql SQL Server 2012 TSQL新函数LAG,LEAD,FIRST_VALUE和LAST_VALUE
如何在spark sql lag函数中添加if或case条件