Отображение всех значений в Group By с включением CASE

У меня есть следующие данные

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

Как вернуть пустые группы в предложении SQL GROUP BY

Любая помощь или ссылки?

Дальнейшее обновление.

Попробовав решение ниже, результаты все еще не появляются. Вставка здесь фактического кода, в котором мне нужно будет применить логику

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 отображался с нулевым счетом.


person VKarthik    schedule 06.03.2014    source источник


Ответы (1)


Я бы сделал это, создав собственную таблицу значений, используя табличное значение. конструктор:

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;

Это даст желаемые результаты.

Пример скрипта SQL


ИЗМЕНИТЬ

Проблема, связанная с тем, как вы выполняете запрос, заключается в том, что, хотя вы сразу же присоединились к 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;
person GarethD    schedule 06.03.2014
comment
Пробовал это, но я не получаю желаемого результата. - person VKarthik; 06.03.2014
comment
Точно. Большое спасибо, и это также помогло мне лучше понять решение. - person VKarthik; 06.03.2014