如何将case语句合并到具有聚合函数的查询中

时间:2017-07-11 10:23:04

标签: sql-server sql-server-2008-r2

我有这个SQL失败,因为case语句中的incidentdate不是group by或aggregate函数的一部分。如果我按事件日期分组,那么我会使聚合函数无用,因为它会为每个时间差异分别设置一行。

所以我想做的是按案例陈述的结果分组,即'Days'或'Nights',我有一个相当垃圾的解决方案,即将数据放入临时表,然后从临时表中选择包括汇总功能,但我相信必须有更好的方法。

我想要的似乎在逻辑上类似于having子句,但用于select。

SELECT    
    d.DeptName,
    CASE
       WHEN DATEPART(hh, nmm.incidentdate) < 6 OR 
            DATEPART(hh, nmm.incidentdate) >= 18 
          THEN 'Nights'
       WHEN DATEPART(hh, nmm.incidentdate) >= 6 AND 
            DATEPART(hh, nmm.incidentdate) < 18 
          THEN 'Days'
    END AS [Shift],
    COUNT(nmm.ReferenceNo)
FROM 
    NearMissesMain nmm
INNER JOIN
    Departments d ON d.DepartmentID = nmm.reporterdepartment 
WHERE
    nmm.DepartmentID = 1
GROUP BY 
    d.DeptName

2 个答案:

答案 0 :(得分:1)

您需要使用派生表。如果你考虑一下你要求SQL做什么,你会看到可能有多个日期,可能是Nights或Days,但希望在一行上。对于相同的参考号,您可以同时拥有Nights和Days。没有在下面进行测试,如果它不是完美的,那么道歉,但希望它能给你这个想法:

SELECT      A.DeptName              ,
            A.[Shift]               ,
            COUNT(A.ReferenceNo)

FROM
(
        SELECT      d.DeptName,
                    CASE WHEN DATEPART(hh, nmm.incidentdate) < 6 or DATEPART(hh, nmm.incidentdate) >= 18 then 'Nights'
                        WHEN DATEPART(hh, nmm.incidentdate) >= 6 and DATEPART(hh, nmm.incidentdate) < 18 then 'Days'
                        END AS [Shift],
                    nmm.ReferenceNo
        FROM        NearMissesMain nmm
        INNER JOIN  Departments d on d.DepartmentID = nmm.reporterdepartment 
        WHERE       nmm.DepartmentID = 1
)   AS  A
GROUP BY    A.DeptName  ,
            A.[Shift]

答案 1 :(得分:0)

您也可以在下面添加以下内容:

group by d.DeptName,
CASE WHEN DATEPART(HH, NMM.INCIDENTDATE) < 6 OR DATEPART(HH, NMM.INCIDENTDATE) >= 18 THEN 'NIGHTS'
WHEN DATEPART(HH, NMM.INCIDENTDATE) >= 6 AND DATEPART(HH, NMM.INCIDENTDATE) < 18 THEN 'DAYS'
END

就足够了