2014-09-30 4 views
1

У меня возникает небольшая проблема с использованием Group By With Rollup при получении CountDistinct.Group With With Rollup and Count (Distinct)

Вопрос заключается в том, что сводка Rollup - это общее количество значений Distinct значений по всем группам, а не сводка всех группировок.

Вот тестовый сценарий, чтобы проиллюстрировать, что я имею в виду:

Create Table #Test 
(
    GroupId Int Not Null, 
    Value Int Not Null 
) 

Insert #Test (GroupId, Value) 
Values (1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(1, 5),(1, 1), 
     (2, 1),(2, 6),(2, 7),(2, 5),(2, 7),(2, 5), 
     (3, 9),(3, 10),(3, 11),(3, 4),(3, 5),(3, 7),(3, 8),(3, 5),(3, 7),(3, 8) 

Для этой конкретной таблицы, если я запускаю этот запрос:

Select Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End As GroupId, 
     Count(Distinct Value) Count 
From #Test 
Group By GroupId With Rollup 
Order By Grouping(GroupId), GroupId 

Я получаю следующий результат:

GroupId Count 
------------- 
1  5 
2  4 
3  7 
Total: 11 

Ожидаемый результат для общей строки будет 16, но вместо этого я получаю только 11 - это общее число Distinct Значения среди всех групп.

Удаление Distinct из запроса действительно показывает ожидаемые результаты этого Rollup:

Select Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End As GroupId, 
     Count(Value) Count 
From #Test 
Group By GroupId With Rollup 
Order By Grouping(GroupId), GroupId 

Что дает следующие результаты:

GroupId Count 
------------- 
1  7 
2  6 
3  10 
Total: 23 

Какие суммирует группы, как и ожидалось.

Мой вопрос: это нормально для Rollup на Count Distinct? Есть ли другой вариант Rollup-like, который можно использовать для Grouping, чтобы отобразить 16, а не 11 в приведенном выше примере?

+0

Вы хотите DISTINCT Результаты в SELECT, но все значения в последней строке сводки? – Mihai

+1

Я хочу отличную оценку для каждой группы и резюме всех групп. Группы показывают правильные подсчеты, но я хотел бы, чтобы строка свертки отображала общее количество всех групп (например, показывало 16, а не 11). – Siyual

ответ

2

Вы можете получить то, что вы хотите, вкладывая запросы и используя трюк:

select GroupId, Sum(Count) as Count 
from (Select (Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End) As GroupId, 
      Count(Distinct Value) as Count 
     From #Test 
     Group By GroupId 
    ) t 
Group By GroupId With Rollup 
Order By Grouping(GroupId), GroupId; 

Второй group by логически не делать агрегацию, потому что есть только одна строка для каждой группы. Это просто для получения нужного значения в rollup.

+0

А - Я надеялся достичь этого без гнезда. Любая идея, почему «Rollup» ведет себя таким образом? – Siyual

+0

@Siyual. , , Сводка включена в 'count (distinct)'. Многие люди считают это поведение хорошим. Сумма различных значений не совпадает с количеством, отличным от объединения вещей. –

+0

А, это имеет смысл.Таким образом, «Rollup» по существу применяет одну и ту же агрегацию ко всем группам в целом, а не применяет одну и ту же совокупность к результатам каждой группы. Это имеет смысл, почему 'Count (Distinct)' будет вести себя именно так. Спасибо за помощь! – Siyual

2

Создание тестовых данных:

DECLARE @Test TABLE 
(
    GroupId Int Not Null, 
    Value Int Not Null 
) 

Insert @Test 
(GroupId, Value) 
Values (1, 1),(1, 2),(1, 3),(1, 4),(1, 5),(1, 5),(1, 1), 
     (2, 1),(2, 6),(2, 7),(2, 5),(2, 7),(2, 5), 
     (3, 9),(3, 10),(3, 11),(3, 4),(3, 5),(3, 7),(3, 8),(3, 5),(3, 7),(3, 8) 

Я изменил третий столбец группы отчетливым групповым идентификатором и значением

Select Case When Grouping(GroupId) = 1 Then 'Total:' Else Str(GroupId) End As GroupId, 
     Count(DISTINCT Value) As Count, 
     Count(Value) AS Count2, 
     Count(DISTINCT (GroupId * 10) + Value) AS Count3 
From @Test 
Group By GroupId With Rollup 
Order By Grouping(GroupId), GroupId 

Вот результат:

GroupId Count Count2 Count3 
1  5  7  5 
2  4  6  4 
3  7  10  7 
Total: 11 23  16