Поворот очень похож на группировку. Вы можете рассматривать это как ограниченную группу с «специальным эффектом». Ограничение состоит в том, что может быть только один агрегированный столбец. (Естественно, в обычном запросе GROUP BY может быть несколько). И под «специальным эффектом» я имею в виду, конечно, что один из других столбцов (и, опять же, только один) преобразуется в несколько столбцов.
Давайте возьмем ваш запрос GROUP BY в качестве примера. У вас есть три столбца на выходе. Одним из них, Count
, является тот самый столбец, который содержит агрегированную информацию. Это тот, который будет разбросан по нескольким столбцам в запросе PIVOT. Другой столбец Priority
- это один из двух других столбцов, по которым сгруппированы результаты, а также столбец, который необходимо повернуть. Наконец, EntryDate
- это другой столбец GROUP BY. Он должен просто оставаться таким, какой он есть, потому что он не принимает непосредственного участия в повороте.
Посмотрим теперь, как ваш основной SELECT преобразуется из обычного запроса GROUP BY в запрос PIVOT, шаг за шагом:
Поскольку в запросе PIVOT подразумевается группировка, предложение GROUP BY удаляется. Вместо этого вводится предложение PIVOT.
Выражение столбца Count
перемещено из предложения SELECT в предложение PIVOT.
Разделение столбца Priority
определено в предложении PIVOT.
Столбцы Priority
и Count
в предложении SELECT заменяются списком столбцов, определенных в предложении PIVOT.
Столбец EntryDate
остается неизменным в предложении SELECT.
И вот результирующий запрос с комментариями, отмечающими каждую часть преобразования, описанного выше:
WITH TATH(Priority, EntryDate) AS
(
SELECT TH.Priority as Priority, DATEADD(dd, 0, DATEDIFF(dd, 0, entryDate)) as EntryDate
FROM TicketAssignment TA, TicketHeader TH
WHERE TA.TicketID = TH.TicketID
AND TA.Company = 'IT'
AND TA.CurrentRole IN ('SA1B','SA1C','SDA')
)
SELECT
convert(varchar(10), EntryDate,103) as EntryDate, -- #5
[0] AS Priority0, [1] AS Priority1, [2] AS Priority2, [3] AS Priority3 -- #4
FROM TATH
PIVOT ( -- #1
COUNT(*) -- #2
FOR Priority IN ([0], [1], [2], [3]) -- #3
) p
/* -- your original main query, for comparison
SELECT
Priority, -- #4
convert(varchar(10), -- #5
EntryDate,103) as EntryDate, COUNT(*) AS Count -- ##2&4
FROM TATH
GROUP BY Priority, EntryDate -- #1
*/
В списке столбцов в предложении PIVOT есть еще одна заметка. Прежде всего, вы должны понимать, что результирующий набор SQL-запросов должен быть фиксированным * с точки зрения количества столбцов и их имен. Это означает, что вы должны явно перечислить все преобразованные столбцы, которые вы хотите видеть в выводе. Имена получаются из значений поворотного столбца, но они должны быть указаны как names , а не как значения. Вот почему вы можете увидеть квадратные скобки вокруг перечисленных номеров. Поскольку сами числа не удовлетворяют правилам для обычных идентификаторов , они должны быть разделены.
Вы также можете видеть, что вы можете использовать псевдонимы для столбцов в предложении SELECT, как и любой другой столбец или выражение. Таким образом, в конце концов, вам не нужно заканчиваться бессмысленными идентификаторами 0
, 1
и т. Д., И вместо этого вы можете присвоить этим столбцам любые имена, которые вам нравятся.
* Если вы хотите, чтобы число и / или имена поворотных столбцов были динамическими, вам придется строить запрос динамически, т.е. сначала собирать имена, затем включите их в строку, содержащую остальную часть запроса, и вызовите окончательный запрос с помощью EXEC ()
или EXEC sp_executesql
. Вы можете поискать на этом сайте для получения дополнительной информации о динамическом повороте.