Использование PIVOT в SQL Server 2008

предположим, у меня есть некоторые данные, либо в таблице SQL Server 2008, либо в переменной [table]:

author_id     review_id     question_id     answer_id
88540         99001         1               719
88540         99001         2               720
88540         99001         3               721
88540         99001         4               722
88540         99001         5               723
36414         24336         1               302
36414         24336         2               303
36414         24336         3               304
36414         24336         4               305
36414         24336         5               306

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

author_id     review_id     1     2     3     4     5
88540         99001         719   720   721   722   723
36414         24336         302   303   304   305   306

Я подозреваю, что оператор PIVOT-это то, что мне нужно (согласно этот пост, во всяком случае), но я не могу понять, как начать, особенно когда количество question_id строки в таблице могут отличаться. В приведенном выше примере, это 5, но в другом запросе таблица может быть заполнена 7 различными вопросами.

5 ответов


на самом деле, вам лучше сделать это в клиенте. Предположим, вы используете службы Reporting Services, получаете данные в соответствии с вашим первым результирующим набором и отображаете их с помощью матрицы, с author_id и review_id в группе строк, question_id в группе столбцов и MAX(answer_id) в середине.

запрос выполним, но вам понадобится динамический SQL прямо сейчас.

...что-то вроде:

DECLARE @QuestionList nvarchar(max);
SELECT @QuestionList = STUFF(
(SELECT ', ' + quotename(question_id)
FROM YourTable
GROUP BY question_id
ORDER BY question_id
FOR XML PATH(''))
, 1, 2, '');

DECLARE @qry nvarchar(max);
SET @qry = '
SELECT author_id, review_id, ' + @QuestionList + 
FROM (SELECT author_id, review_id, question_id, answer_id
      FROM YourTable
     ) 
PIVOT
(MAX(AnswerID) FOR question_id IN (' + @QuestionList + ')) pvt
ORDER BY author_id, review_id;';

exec sp_executesql @qry;

здесь у вас есть отличный пример и объяснение.

в вашем случае это будет выглядеть так:

SELECT author_id, review_id, [1], [2], [3], [4], [5]
FROM 
    (
        SELECT author_id, review_id, question_id, answer_id
        FROM the_table
    ) up
PIVOT (MAX(answer_id) FOR question_id IN ([1],[2],[3],[4],[5])) AS pvt

SELECT author_id, review_id, [1], [2], [3], [4], [5]
FROM 
    (
        SELECT author_id, review_id, question_id, answer_id
        FROM the_table
    ) up
PIVOT (MAX(answer_id) FOR

select * 
from @t pivot
(
    max(answer_id) for question_id in ([1],[2],[3],[4],[5])
) pivotT

единственный способ изменить список ([1],[2],[3],[4],[5]) будет построить этот запрос в строке (динамически), а затем выполнить его.


посмотреть ответ

в основном, вы предварительно проверяете данные, чтобы получить столбцы, а затем динамически генерируете SQL, используя динамический сводный список. Нет не динамично, поскольку определение столбцов в наборе, который вы хотите вернуть не фиксируется.