如果任何行为 NULL,则 returns NULL 组内的移动平均值(雪花 - SQL)
Moving average within groups that returns NULL if any row is NULL (Snowflake - SQL)
我需要计算每组列的移动平均值(按 id
划分)。唯一的转折是,如果相应 window 中的任何值为 NULL,我需要结果为 NULL。
预期行为示例(对于给定的 id
和 window 尺寸=3):
A
mov_ave_A
NULL
NULL
1
NULL
1
NULL
1
1
4
2
移动平均的前3行是NULL,因为第一个值(包含在前3windows中)是NULL。 mov_ave_A
的第 4 行等于 1,因为它是 A
的第 2 行到第 4 行的平均值,依此类推。
我试过了:
CASE WHEN SUM(CASE WHEN a IS NULL THEN 1 ELSE 0 END) = 0 THEN AVG(a) ELSE NULL END
OVER (
PARTITION BY id
ORDER BY date_month
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS mov_ave_A
但我明白了
"Sliding window frame unsupported for function CASE".
此外,我真的希望解决方案简短明了,因为我需要创建 6 个这样的列。所以,我必须重复逻辑 6 次。
使用以下大小写表达式:
CASE WHEN COUNT(a) OVER (
PARTITION BY id
ORDER BY date_month
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) = 3 THEN AVG(a) OVER (
PARTITION BY id
ORDER BY date_month
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) END AS mov_avg
您的查询的问题是 OVER 子句在 END 之后。我相信这应该有效。您需要为每个 window 函数设置 OVER 子句,一次用于 COUNT,一次用于 AVG。 COUNT 是一种更容易检查 NULL 的方法,然后使用 SUM
SELECT
*
,CASE
/*Check for 3 values in a, if so return the rolling AVG value. Implicit ELSE NULL*/
WHEN COUNT(a) OVER (PARTITION BY ID ORDER BY date_month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) = 3
THEN AVG(a) OVER (PARTITION BY ID ORDER BY date_month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
END AS mov_ave_A
FROM YourTable
我需要计算每组列的移动平均值(按 id
划分)。唯一的转折是,如果相应 window 中的任何值为 NULL,我需要结果为 NULL。
预期行为示例(对于给定的 id
和 window 尺寸=3):
A | mov_ave_A |
---|---|
NULL | NULL |
1 | NULL |
1 | NULL |
1 | 1 |
4 | 2 |
移动平均的前3行是NULL,因为第一个值(包含在前3windows中)是NULL。 mov_ave_A
的第 4 行等于 1,因为它是 A
的第 2 行到第 4 行的平均值,依此类推。
我试过了:
CASE WHEN SUM(CASE WHEN a IS NULL THEN 1 ELSE 0 END) = 0 THEN AVG(a) ELSE NULL END
OVER (
PARTITION BY id
ORDER BY date_month
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS mov_ave_A
但我明白了
"Sliding window frame unsupported for function CASE".
此外,我真的希望解决方案简短明了,因为我需要创建 6 个这样的列。所以,我必须重复逻辑 6 次。
使用以下大小写表达式:
CASE WHEN COUNT(a) OVER (
PARTITION BY id
ORDER BY date_month
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) = 3 THEN AVG(a) OVER (
PARTITION BY id
ORDER BY date_month
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) END AS mov_avg
您的查询的问题是 OVER 子句在 END 之后。我相信这应该有效。您需要为每个 window 函数设置 OVER 子句,一次用于 COUNT,一次用于 AVG。 COUNT 是一种更容易检查 NULL 的方法,然后使用 SUM
SELECT
*
,CASE
/*Check for 3 values in a, if so return the rolling AVG value. Implicit ELSE NULL*/
WHEN COUNT(a) OVER (PARTITION BY ID ORDER BY date_month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) = 3
THEN AVG(a) OVER (PARTITION BY ID ORDER BY date_month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
END AS mov_ave_A
FROM YourTable