Запрос SQL Server: строки составляют столбцы (Pivot?) - PullRequest
1 голос
/ 01 декабря 2011

У меня есть проблема, чтобы сделать запрос.

Этот запрос, который я создал

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 Priority, convert(varchar(10), EntryDate,103) as EntryDate, COUNT(*) AS Count  
FROM TATH 
GROUP BY Priority, EntryDate 

и результат пока:

Priority    EntryDate   Count
0   25/11/2011  1
1   25/11/2011  2
2   25/11/2011  36
3   25/11/2011  8
0   28/11/2011  3
1   28/11/2011  3
2   28/11/2011  37
3   28/11/2011  37

Я хочу, чтобы результат выглядел следующим образом

EntryDate   Priorty0    Priority1   Priority2   Priority3
25/11/2011  1   2   36  8
28/11/2011  3   3   37  37

Я думаю, что из-за своих способностей я смотрю в центр, но не могу этого достичь.

Если поворот не является хорошим решением, что мне искать (или изучать)?

Не могли бы вы помочь мне Q.Q?

1 Ответ

2 голосов
/ 05 декабря 2011

Поворот очень похож на группировку. Вы можете рассматривать это как ограниченную группу с «специальным эффектом». Ограничение состоит в том, что может быть только один агрегированный столбец. (Естественно, в обычном запросе GROUP BY может быть несколько). И под «специальным эффектом» я имею в виду, конечно, что один из других столбцов (и, опять же, только один) преобразуется в несколько столбцов.

Давайте возьмем ваш запрос GROUP BY в качестве примера. У вас есть три столбца на выходе. Одним из них, Count, является тот самый столбец, который содержит агрегированную информацию. Это тот, который будет разбросан по нескольким столбцам в запросе PIVOT. Другой столбец Priority - это один из двух других столбцов, по которым сгруппированы результаты, а также столбец, который необходимо повернуть. Наконец, EntryDate - это другой столбец GROUP BY. Он должен просто оставаться таким, какой он есть, потому что он не принимает непосредственного участия в повороте.

Посмотрим теперь, как ваш основной SELECT преобразуется из обычного запроса GROUP BY в запрос PIVOT, шаг за шагом:

  1. Поскольку в запросе PIVOT подразумевается группировка, предложение GROUP BY удаляется. Вместо этого вводится предложение PIVOT.

  2. Выражение столбца Count перемещено из предложения SELECT в предложение PIVOT.

  3. Разделение столбца Priority определено в предложении PIVOT.

  4. Столбцы Priority и Count в предложении SELECT заменяются списком столбцов, определенных в предложении PIVOT.

  5. Столбец 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. Вы можете поискать на этом сайте для получения дополнительной информации о динамическом повороте.

...