Предположим, у меня есть таблица, в которой хранятся имена клиентов, номера устройств и несколько флагов. Некоторые выборки данных выглядит примерно так:Подведите данные двумя разными способами.
[CustomerName], [Device], [A], [B], [C]
'Customer A', '1234', 1, 0, 0
'Customer A', '1235', 1, 1, 1
'Customer A', '1234', 1, 1, 1
'Customer B', '1236', 1, 1, 0
'Customer B', '1236', 1, 0, 0
'Customer C', '1235', 1, 1, 1
Мне нужен доклад, содержащий 3-х типов данных одновременно:
- Общее количество строк с каждым флагом
- Число строк с каждой флаг для каждого клиента
- количество уникальных устройств, которые появляются в любой строке с каждым флагом
Первые два предмета были относительно просты в создании с использованием ROLLUP
, но последний элемент был более сложным. Единственный способ, которым я мог понять, как сделать это с UNION
:
SELECT CASE WHEN (GROUPING([CustomerName]) = 1) THEN 'ALL CUSTOMERS'
ELSE [CustomerName] END [CustomerName],
COUNT(*) [Rows],
SUM(CAST([A] AS [int])) [A],
SUM(CAST([B] AS [int])) [B],
SUM(CAST([C] AS [int])) [C]
FROM [MyTable]
GROUP BY [CustomerName] WITH ROLLUP
UNION
SELECT 'UNIQUE DEVICES',
COUNT(*),
SUM(CASE WHEN [A] > 0 THEN 1 ELSE 0 END),
SUM(CASE WHEN [B] > 0 THEN 1 ELSE 0 END),
SUM(CASE WHEN [C] > 0 THEN 1 ELSE 0 END)
FROM (
SELECT [Device],
COUNT(*) [Rows],
SUM(CAST([A] AS [int])) [A],
SUM(CAST([B] AS [int])) [B],
SUM(CAST([C] AS [int])) [C]
FROM [MyTable]
GROUP BY [Device]) q
Результаты:
[CustomerName], [Rows], [A], [B], [C]
'ALL CUSTOMERS', 6, 6, 4, 3
'Customer A', 3, 3, 2, 2
'Customer B', 2, 2, 1, 0
'Customer C', 1, 1, 1, 1
'UNIQUE DEVICES', 3, 3, 3, 2
Это работает достаточно хорошо для моих целей в настоящее время, но, не имел большого опыта работы с ROLLUP
или CUBE
раньше, я думал, что постараюсь посмотреть, смогу ли я избавиться от этого UNION
и у вас есть SELECT
. С examples on MSDN, ROLLUP
поддерживает несколько группировок, но я не могу понять, как получить его для получения результатов, которые я хочу. Может ли кто-нибудь продемонстрировать, как использовать один SELECT
, чтобы получить эти результаты?
Группировка, свертывание и куб являются иерархическими, но желаемого результата нет. То, что вы сделали, - это единственный способ получить нужный результат :) –
@ P.Salmon Это то, чего я боялся, но я продолжаю думать, что это возможно, если я использую двойную агрегацию, как это было в второй SELECT. –
Есть способы получить это в «одном» запросе (т. Е. Не использовать UNION), но все они будут включать более сложный/менее понятный/менее эффективный код, чем тот, который у вас уже есть. Я могу опубликовать пример позже, если вы действительно захотите, или можете принять, что @ P.Salmon в основном ударил его по голове. – Jeff