SQL - 如何在窗口函数中应用条件范围规范

问题描述 投票:0回答:1

我每月总结最后 3 个月的值,因此我使用一个窗口来实现这一点。

SELECT
    [month],
    ROUND(
        SUM(
            ISNULL(
                CAST( val AS DECIMAL(10, 2) ),
                0
            )
        ) OVER (
            ORDER BY month
            ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
        ) / 3,
        2
    ) as sum_val
FROM
    myTable
;

我需要使用下一行或下一行和上一行而不是前两行,它们不存在。我正在寻找类似这样的语法。

SELECT
    [month],
    ROUND(
        SUM(
            ISNULL(
                CAST( val AS DECIMAL(10, 2) ),
                0
            )
        ) OVER (
            ORDER BY [month]
            ROWS BETWEEN
                CASE
                    WHEN [month] = 1
                    THEN CURRENT ROW AND 2 FOLLOWING
                    WHEN [month] = 2
                    THEN 1 PRECEDING AND 1 FOLLOWING
                    ELSE 2 PRECEDING AND CURRENT ROW
                END
        ) / 3,
        2
    ) AS sum_val
FROM
    myTable
;

我无法在 Microsoft SQL 文档中找到表达此要求的语法。

Microsoft Over 子句文档

我不想在外面多次使用 CASE 语句进行计算,如果需要的话,阅读和编辑会很糟糕。

样本数据:

val
1 0
2 0
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1

预期产出:

sum_val
1 1
2 1
3 1
4 2
5 3
6 3
7 3
8 3
9 3
10 3
11 3
12 3
sql-server window-functions
1个回答
0
投票
SELECT
    [month],
    (
        SUM(val) OVER (ORDER BY "month" ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) +
        CASE WHEN "month" IN (1, 2) THEN LEAD(val, 1) OVER (ORDER BY month) else 0 end +
        CASE WHEN "month" IN (1)    THEN LEAD(val, 2) OVER (ORDER BY month) else 0 end
    ) * 1.0 AS sum_val
FROM T;

with augmented as (
    select "month", val from T union all
    select "month" - 2, val from T where "month" in (1, 2)
), data as (
    SELECT
        "month",
        SUM(val) OVER (
            ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) * 1.0 as sum_val
    FROM augmented
)
select * from data where "month" > 0;

https://dbfiddle.uk/80-zj_xW

© www.soinside.com 2019 - 2024. All rights reserved.