想知道是否存在对分析功能的内置支持,这些支持不应用于我的SQL查询的前 n 行。
示例代码:
;with cte (num, dollar) as
(
select 1, cast(1.45 as decimal(12,2))
union all
select num + 1, cast(dollar + 1.00 as decimal(12,2))
from cte
where num < 20
)
select cte.num, cte.dollar
, avg(cte.dollar) over (order by cte.num ROWS 3 PRECEDING) as ThreeMonthAvg
, avg(cte.dollar) over (order by cte.num ROWS 6 PRECEDING) as SixMonthAvg
from cte
在这里,我分别获得了三个月和六个月美元的滚动平均值。显然,这将为每一行填充依赖于分析平均数的那些列的值。但是,由于不是真正的第1行和第2行的前三行的平均值,因此无论什么工作,我都希望显示0,null。
我当前的解决方案:在我的实际设置中使用row_number()
来使用rownum,或者在此为测试用例使用递归构造的行num。无论如何,而不是个案说明。
--solution
;with cte (num, dollar) as
(
select 1, cast(1.45 as decimal(12,2))
union all
select num + 1, cast(dollar + 1.00 as decimal(12,2))
from cte
where num < 20
)
select cte.num, cte.dollar
, case when cte.num >= 3 then avg(cte.dollar) over (order by cte.num ROWS 3 PRECEDING) else 0 end as ThreeMonthAvg
, case when cte.num >= 6 then avg(cte.dollar) over (order by cte.num ROWS 6 PRECEDING) else 0 end as SixMonthAvg
from cte
是否存在一种内置的方法来告诉该函数“跳过”该函数以将其应用于前n个行,而不是将该行从结果集中过滤掉?
检查了Microsoft文档,但我自己找不到支持或否认的任何内容。
答案 0 :(得分:1)
没有内置方法,但是此版本可在更多情况下使用:
with cte (num, dollar) as (
select 1, cast(1.45 as decimal(12,2))
union all
select num + 1, cast(dollar + 1.00 as decimal(12,2))
from cte
where num < 20
)
select cte.num, cte.dollar,
(case when count(*) over (order by cte.num ROWS 3 PRECEDING) = 3
then avg(cte.dollar) over (order by cte.num ROWS 3 PRECEDING)
end) as ThreeMonthAvg,
(case when count(*) over (order by cte.num ROWS 6 PRECEDING) = 6
then avg(cte.dollar) over (order by cte.num ROWS 6 PRECEDING)
end) as SixMonthAvg
from cte;
这实际上是计算进入平均值的行,而不是取决于特定的数值。