如何在没有sum()over()的情况下根据列值进行分组和求和?

时间:2016-03-18 20:51:19

标签: sql-server sql-server-2008 tsql

我们有一个表[Kpis],如下所示:

AUTH_USER_MODEL

我想按照EmpId,KpiName,Date,Hour进行分组。因此,例如,对于此数据, 时, K12 Kpi1

所以我尝试使用CASE语句,但结果不正确。我没有检查结果中的实际总数,但总和应该是正确的。这是结果的格式不正确;每个empid都有两行:一行用于Kpi1,另一行用于Kpi2。

RawId   EmpId     Date         Hour  Min   KpiValue   KpiName
106     ABC123    20160310     8     0     3           Kpi1
124     ABC123    20160310     8     0     65          Kpi1
121     ABC123    20160310     8     15    12          Kpi2
109     ABC109    20160310     8     0     34          Kpi2
112     ABC908    20160310     9     5     3           Kpi1
118     ABC907    20160310     8     30    24          Kpi1
115     ABC123    20160310     8     15    54          Kpi1

如何使用Case语句来修复结果?

感谢。

3 个答案:

答案 0 :(得分:0)

SUM功能必须在CASE之外:

select empid, 
    sum(case kpiname when 'Kpi1' then kpivalue end) as 'Kpi1',
    sum(case kpiname when 'Kpi2' then kpivalue end) as 'Kpi2'
from 
    [Kpis]
where kpiname in ('Kpi1', 'Kpi2')
and date = 20160310 and hour = 8
group by empid, kpiname, hour

答案 1 :(得分:0)

将案例放在你的总和中,这样每个KpiName只对相关值求和。

SELECT
    EmpId,
    [Hour], 
    SUM(
        CASE
            WHEN KpiName = 'Kpi1' THEN KpiValue
            ELSE 0
        END
    ) Kpi1,
    SUM(
        CASE
            WHEN KpiName = 'Kpi2' THEN KpiValue
            ELSE 0
        END
    ) Kpi2
FROM
    Kpis
GROUP BY
    EmpId,
    [Hour]

这会产生此输出

EmpId   Hour    Kpi1    Kpi2
ABC109  8       0       34
ABC123  8       122     12
ABC907  8       24      0
ABC908  9       3       0

答案 2 :(得分:0)

您也可以使用PIVOT功能执行此操作,我认为这是您实际尝试完成的功能。

SELECT
    *
FROM (
    SELECT
        EmpId,
        KpiName,
        [Hour],
        KpiValue
    FROM
        Kpis
) SourceTable

PIVOT (
    SUM(KpiValue)
    FOR KpiName
    IN ([Kpi1],[Kpi2])
) PivotTable

这给出了这个输出。注意NULL而不是零,正确地显示缺少数据。

EmpId   Hour    Kpi1    Kpi2
ABC109  8       NULL    34
ABC123  8       122     12
ABC907  8       24      NULL
ABC908  9       3       NULL