Это, конечно, довольно стандартный PIVOT
запрос. Вот более идиоматическая версия для SQL Server:
SELECT User_Master.name, [1] AS Transferred, [2] AS Routed, [3] AS Disconnected
FROM (SELECT userId, callType
FROM Call_Master) Call_Master
PIVOT(COUNT(callType) FOR callType IN ([1], [2], [3])) Pivoted
JOIN User_Master
ON User_Master.userId = Pivoted.userId
Демонстрация SQL Fiddle
Агрегат, кажется, происходит до объединения с User_Master
, поэтому запрос должен иметь возможность использовать индексы для выполнения COUNT(*)
. К сожалению, нет способа автоматически заполнять псевдонимы столбцов - для этого вам понадобится динамический SQL.
EDIT:
Пояснения -
(SELECT userId, callType
FROM Call_Master) Call_Master
Этот подзапрос получает список столбцов, по которым будет группироваться и запускаться агрегат. Вы можете сделать любые условия для проверки диапазона и тому подобное. Намерение состоит в том, что запрос должен быть тем, что вы написали бы для GROUP BY
... просто без этого предложения и агрегата.
PIVOT(COUNT(callType) FOR callType IN ([1], [2], [3])) Pivoted
В этом разделе система сообщает "для предыдущей ссылки на таблицу, запустите данный агрегат по указанному столбцу и для каждого изменения в другом (потенциально другом) столбце поместите результат в новый столбец". Есть несколько предостережений:
- Все остальные столбцы будут включены в то, что по существу составляет
GROUP BY
пункт
- Вы можете указать только одну статистическую функцию
- Вы можете указать только один столбец в совокупности и только столбец (здесь нет математики). Вам нужно сделать что-то подобное в подзапросе
- Список столбцов в предложении
IN
должен содержать все значения, возвращаемые вашим подзапросом, но также может иметь столбцы без результатов. Если вы пропустите [2]
, вы получите ошибку во время выполнения, но добавление [4]
просто даст вам столбец с 0
s
- Обязательные скобки, и если столбец, указанный в предложении
FOR
, является символьным, вы не используете кавычки вокруг значений.
Псевдоним для таблицы результатов (Pivoted
здесь) является обязательным и действует для всех столбцов. На данный момент в запросе нет столбца Call_Master.userId
.
ПРИСОЕДИНЯЙТЕСЬ к User_Master
ON User_Master.userId = Pivoted.userId
... И, наконец, соединение с User_Master
для перевода идентификаторов пользователей в имена. Обратите внимание: поскольку агрегат происходит «внутри» ссылки, сгенерированной как часть запроса Pivot
, вам не нужно беспокоиться о странных вещах, происходящих с остальными данными.