使用sum aggregate / pivoting

时间:2016-01-20 08:30:37

标签: sql sql-server pivot-table

考虑这个24小时的摘要。问题是,我已经在0小时内返回0,但尚未插入值。我认为这是由于 SUM() 函数调用。

SELECT
    section,
    [21], [22], [23], [0], [1], [2], [3], [4], [5], [6], [7], [8],
    [21] + [22] + [23] + [0] + [1] + [2] + [3] + [4] + [5] + [6] + [7] + [8] as s1_total
    -- shift 2 fields are ommitted for brievity
FROM (
    SELECT 
        section,
        -- hours from 21:00 (1st shift) to 20:00 (2nd shift)
        SUM(CASE WHEN prTime = '21:00:00' THEN Amount ELSE 0 END) AS [21],
        SUM(CASE WHEN prTime = '22:00:00' THEN Amount ELSE 0 END) AS [22],
        SUM(CASE WHEN prTime = '23:00:00' THEN Amount ELSE 0 END) AS [23],
        SUM(CASE WHEN prTime = '00:00:00' THEN Amount ELSE 0 END) AS [0],
        SUM(CASE WHEN prTime = '01:00:00' THEN Amount ELSE 0 END) AS [1],
        SUM(CASE WHEN prTime = '02:00:00' THEN Amount ELSE 0 END) AS [2],           
        -- ... similar cases are omitted for brieviety
        SUM(CASE WHEN prTime = '20:00:00' THEN Amount ELSE 0 END) AS [20]
    FROM (
        SELECT prTime, prDate, section01 AS Amount, 'section 1' as [Section] FROM SectionsHourlyValues
        UNION
        SELECT prTime, prDate, section02 AS Amount, 'section 2' as [Section] FROM SectionsHourlyValues
        UNION
        SELECT prTime, prDate, section03 AS Amount, 'section 3' as [Section] FROM SectionsHourlyValues
    ) AS U
    WHERE 
        (prDate = CONVERT(DATE, DATEADD(HOUR, -4, CONVERT(DATETIME2(7), @dt, 104))) and prTime > '20:00:00') or 
        (prDate = CONVERT(DATE, @dt, 104) and prTime <= '20:00:00')
    GROUP BY section
) t;

例如,运行查询

DECLARE @dt varchar(10) = 'certain_date';
SELECT * from [dbo].[SectionsHourlyValues] WHERE
    (prDate = CONVERT(DATE, DATEADD(HOUR, -4, CONVERT(DATETIME2(7), @dt, 104))) and prTime > '20:00:00') or 
    (prDate = CONVERT(DATE, @dt, 104) and prTime <= '20:00:00');

不会向我们返回说明 09:00:00 / section1 的数据,而摘要会向我们显示 0

然后我想显示 NULL (对于尚未插入的记录),而不是 0 。我该怎么做?

3 个答案:

答案 0 :(得分:1)

使用NULLIF

NULLIF(SUM(CASE WHEN prTime = '21:00:00' THEN Amount ELSE 0 END),0)

或者根本不使用ELSE

SUM(CASE WHEN prTime = '21:00:00' THEN Amount END)

答案 1 :(得分:1)

如何在条件聚合中用NULL替换0?

SUM(CASE WHEN etc... ELSE NULL END)

答案 2 :(得分:1)

你得到的0值不是由于SUM函数尚未插入的值(这将是NULL并且会被SUM函数忽略),而是因为你的CASE语句的ELSE返回0:

SUM(CASE WHEN prTime = '21:00:00' THEN Amount ELSE 0 END) AS [21]

要解决您的问题,您可以使用与NULLIF非常相似的CASE

NULLIF(MyExpressionThatCouldReturn0, 0)

在你的情况下,那将是:

NULLIF(SUM(CASE WHEN prTime = '01:00:00' THEN Amount ELSE 0 END),0)

否则,如前所述,不要在CASE语句中使用ELSE,用作SUM的参数:

SUM(CASE WHEN prTime = '21:00:00' THEN Amount END)