显示分组依据中包含CASE的所有值

时间:2014-03-06 15:34:26

标签: sql sql-server-2008 tsql

我有以下数据

CREATE TABLE #Test
(
    Severity    NVARCHAR(50)
    ,WorkId     INT
)

INSERT INTO #Test VALUES('High',1)
INSERT INTO #Test VALUES('Critical',2)

SELECT
    CASE 
        WHEN Severity IN ('High','Critical') THEN 'Critical'
        WHEN Severity IN ('Low','Medium') THEN 'Medium'
    END AS 'Severity'
    ,COUNT(*) AS 'Total'
FROM #Test 
GROUP BY 
    CASE 
        WHEN Severity IN ('High','Critical') THEN 'Critical'
        WHEN Severity IN ('Low','Medium') THEN 'Medium'
    END

这导致输出 -

Severity | Total
---------+-------
Critical |   2

我期待以下输出 -

Severity | Total
---------+-------
Critical |   2
 Medium  |   0

我已经查看了以下两个链接,详细说明了类似的情况,但不一样,我仍然无法得到结果 -

http://ask.sqlservercentral.com/questions/47705/showing-null-values-as-well-in-group-by-in-sql.html

How to return empty groups in SQL GROUP BY clause

任何帮助或链接?

进一步更新。

尝试了以下解决方案后,结果仍然没有出现。在这里粘贴实际代码,其中我需要应用逻辑

SELECT  s.NewSeverity AS 'Severity'
        ,COUNT(WI.microsoft_vsts_common_severity) AS 'Total'
FROM   ( VALUES
            ('Critical','I-High')
            ,('High','I-High')
            ,('Medium','I-Low')
            ,('Low','I-Low')
        )s(OldSeverity,NewSeverity)
       LEFT JOIN DimWorkItem WI (NOLOCK) 
            ON WI.microsoft_vsts_common_severity = s.OldSeverity
       JOIN dbo.DimPerson P 
         ON p.personsk = WI.system_assignedto__personsk 
       JOIN DimTeamProject TP 
         ON WI.TeamProjectSK = TP.ProjectNodeSK 
       JOIN DimIteration Itr (NOLOCK) 
         ON Itr.IterationSK = WI.IterationSK 
       JOIN DimArea Ar (NOLOCK) 
         ON Ar.AreaSK = WI.AreaSK 
WHERE  TP.ProjectNodeName = 'ABC' 
       AND WI.System_WorkItemType = 'Bug' 
       AND WI.Microsoft_VSTS_CMMI_RootCause <> 'Change Request' 
       AND Itr.IterationPath LIKE '%\ABC\R1234\Test\IT%' 
       AND WI.System_State NOT IN ( 'Rejected', 'Closed' ) 
       AND WI.System_RevisedDate = CONVERT(datetime, '9999', 126)            
GROUP BY s.NewSeverity

实际上只有两个'低'项,因此我得到的输出是I-Low,2而我想要甚至I-High以0计数出现。

1 个答案:

答案 0 :(得分:3)

我的方法是使用table value constructor创建自己的值表:

SELECT  OldSeverity, NewSeverity
FROM    (VALUES 
            ('Critical', 'Critical'),
            ('High', 'Critical'),
            ('Medium', 'Medium'),
            ('Low', 'Medium')
        ) s (OldSeverity, NewSeverity);

这提供了一个您可以选择的表格,然后左键加入现有的表格:

SELECT  Severity = s.NewSeverity,
        Total = COUNT(t.Severity)
FROM    (VALUES 
            ('Critical', 'Critical'),
            ('High', 'Critical'),
            ('Medium', 'Medium'),
            ('Low', 'Medium')
        ) s (OldSeverity, NewSeverity)
        LEFT JOIN #Test t
            ON t.Severity = s.OldSeverity
GROUP BY s.NewSeverity;

这将产生预期的结果。

<强> Example on SQL Fiddle


编辑

您对查询提出的方式存在的问题是,虽然您已立即离开加入DimWorkItem,但您将内部联接到后续表并引用WorkItem中的列where子句,它撤消你的左连接并将其转回内连接。您需要将整个逻辑放入子查询中,并将其连接到此:

SELECT  s.NewSeverity AS 'Severity'
        ,COUNT(WI.microsoft_vsts_common_severity) AS 'Total'
FROM   ( VALUES
            ('Critical','I-High')
            ,('High','I-High')
            ,('Medium','I-Low')
            ,('Low','I-Low')
        )s(OldSeverity,NewSeverity)
       LEFT JOIN 
       (    SELECT  wi.Severity
            FROM    DimWorkItem WI (NOLOCK) 
                   JOIN dbo.DimPerson P 
                     ON p.personsk = WI.system_assignedto__personsk 
                   JOIN DimTeamProject TP 
                     ON WI.TeamProjectSK = TP.ProjectNodeSK 
                   JOIN DimIteration Itr (NOLOCK) 
                     ON Itr.IterationSK = WI.IterationSK 
                   JOIN DimArea Ar (NOLOCK) 
                     ON Ar.AreaSK = WI.AreaSK 
            WHERE  TP.ProjectNodeName = 'ABC' 
                   AND WI.System_WorkItemType = 'Bug' 
                   AND WI.Microsoft_VSTS_CMMI_RootCause <> 'Change Request' 
                   AND Itr.IterationPath LIKE '%\ABC\R1234\Test\IT%' 
                   AND WI.System_State NOT IN ( 'Rejected', 'Closed' ) 
                   AND WI.System_RevisedDate = CONVERT(datetime, '9999', 126)         
        ) WI
            ON WI.Severity = s.OldSeverity   
GROUP BY s.NewSeverity;