T-SQL 不要忽略 SUM 中的 NULL 值
T-SQL Do not ignore NULL values in SUM
我正在尝试将 运行 总计添加到 table,在 NULL 值上,运行 总计应该为 NULL。但是 SUM 忽略 NULL 值。
有没有办法不忽略 SUM 中的 NULL?
SELECT
run_key,
time_empty,
SUM(time_empty) OVER (PARTITION BY col1, col2 ORDER BY run_key ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as time_empty_rt
FROM
tblmytable
ORDER BY
run_key
我看不出除了分两步来解决这个问题,首先是 gaps and islands problem 确定要总结的岛屿,然后再进行总结。首先是岛屿:
DECLARE @T TABLE (run_key INT, time_empty INT, Col1 INT, Col2 INT)
INSERT @T (run_key, time_empty)
VALUES
(1, 637), (2, NULL), (3, NULL), (4, NULL),
(5, 2967), (6, 1000), (7, NULL), (8, NULL);
SELECT run_key,
time_empty,
IslandID = ROW_NUMBER() OVER(ORDER BY Run_key) -
ROW_NUMBER()
OVER(PARTITION BY
Col1,
Col2,
CASE WHEN time_empty IS NULL THEN 1 ELSE 0 END
ORDER BY Run_key)
FROM @T
ORDER BY run_key;
给出:
run_key time_empty IslandID
------------------------------
1 637 0
2 NULL 1
3 NULL 1
4 NULL 1
5 2967 3
6 1000 3
7 NULL 3
8 NULL 3
这现在为您提供了一个要分区的列 (IslandID
),它将在下一个非空时正确地重置您的总和:
DECLARE @T TABLE (run_key INT, time_empty INT, Col1 INT, Col2 INT)
INSERT @T (run_key, time_empty)
VALUES
(1, 637), (2, NULL), (3, NULL), (4, NULL),
(5, 2967), (6, 1000), (7, NULL), (8, NULL);
SELECT run_key,
time_empty,
time_empty_rt = CASE WHEN time_empty IS NULL THEN NULL
ELSE SUM(time_empty)
OVER (PARTITION BY Col1, Col2, IslandID
ORDER BY run_key
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
END
FROM ( SELECT run_key,
time_empty,
Col1,
Col2,
IslandID = ROW_NUMBER() OVER(ORDER BY Run_key)
- ROW_NUMBER()
OVER(PARTITION BY
Col1,
Col2,
CASE WHEN time_empty IS NULL THEN 1 ELSE 0 END
ORDER BY Run_key)
FROM @T
) AS t;
您可以为具有相同数量的前面 null
列的每个组创建一个分区。
select run_key
, time_empty
, sum(time_empty) over (
partition by preceding_nulls
order by run_key
rows between unbounded preceding and current row) as time_emtpy_rt
from (
select sum(case when time_empty is null then 1 else 0 end) over (
order by run_key
rows between unbounded preceding and current row) as preceding_nulls
, *
from YourTable yt
) sub
我正在尝试将 运行 总计添加到 table,在 NULL 值上,运行 总计应该为 NULL。但是 SUM 忽略 NULL 值。
有没有办法不忽略 SUM 中的 NULL?
SELECT
run_key,
time_empty,
SUM(time_empty) OVER (PARTITION BY col1, col2 ORDER BY run_key ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as time_empty_rt
FROM
tblmytable
ORDER BY
run_key
我看不出除了分两步来解决这个问题,首先是 gaps and islands problem 确定要总结的岛屿,然后再进行总结。首先是岛屿:
DECLARE @T TABLE (run_key INT, time_empty INT, Col1 INT, Col2 INT)
INSERT @T (run_key, time_empty)
VALUES
(1, 637), (2, NULL), (3, NULL), (4, NULL),
(5, 2967), (6, 1000), (7, NULL), (8, NULL);
SELECT run_key,
time_empty,
IslandID = ROW_NUMBER() OVER(ORDER BY Run_key) -
ROW_NUMBER()
OVER(PARTITION BY
Col1,
Col2,
CASE WHEN time_empty IS NULL THEN 1 ELSE 0 END
ORDER BY Run_key)
FROM @T
ORDER BY run_key;
给出:
run_key time_empty IslandID
------------------------------
1 637 0
2 NULL 1
3 NULL 1
4 NULL 1
5 2967 3
6 1000 3
7 NULL 3
8 NULL 3
这现在为您提供了一个要分区的列 (IslandID
),它将在下一个非空时正确地重置您的总和:
DECLARE @T TABLE (run_key INT, time_empty INT, Col1 INT, Col2 INT)
INSERT @T (run_key, time_empty)
VALUES
(1, 637), (2, NULL), (3, NULL), (4, NULL),
(5, 2967), (6, 1000), (7, NULL), (8, NULL);
SELECT run_key,
time_empty,
time_empty_rt = CASE WHEN time_empty IS NULL THEN NULL
ELSE SUM(time_empty)
OVER (PARTITION BY Col1, Col2, IslandID
ORDER BY run_key
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
END
FROM ( SELECT run_key,
time_empty,
Col1,
Col2,
IslandID = ROW_NUMBER() OVER(ORDER BY Run_key)
- ROW_NUMBER()
OVER(PARTITION BY
Col1,
Col2,
CASE WHEN time_empty IS NULL THEN 1 ELSE 0 END
ORDER BY Run_key)
FROM @T
) AS t;
您可以为具有相同数量的前面 null
列的每个组创建一个分区。
select run_key
, time_empty
, sum(time_empty) over (
partition by preceding_nulls
order by run_key
rows between unbounded preceding and current row) as time_emtpy_rt
from (
select sum(case when time_empty is null then 1 else 0 end) over (
order by run_key
rows between unbounded preceding and current row) as preceding_nulls
, *
from YourTable yt
) sub