2009-11-05 4 views
7

Скажем, у меня есть некоторые данные, либо в таблице SQL Server 2008 или [таблица] -typed переменная:Использование PIVOT в SQL Server 2008

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, что мне нужно (по this post, во всяком случае), но я не могу понять, как приступить к работе, особенно когда число question_id строк таблица может отличаться. В приведенном выше примере это 5, но в другом запросе таблица может быть заполнена 7 различными вопросами.

ответ

9

На самом деле вам будет лучше делать это в клиенте. Предположим, вы используете службы Reporting Services, получаете данные в соответствии с вашим первым набором результатов и отображаете его с использованием матрицы, с author_id и review_id в группе Row, 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; 
+0

Это, кажется, то, что мне нужно. Я дам ему выстрел и отчитаю - спасибо! –

+1

Обратите внимание на подзапрос. Если вы просто используете «SELECT * FROM YourTable», то любые другие задействованные столбцы повлияют на неявную группировку, предоставляемую функцией PIVOT. И если у вас есть какие-либо ошибки, закомментируйте строку 'exec', заменив ее на' select @ qry' –

+0

. Я больше не использую [SELECT *] - я всегда четко указываю столбцы, к которым я обращаюсь, - так что это не будет вопрос. И да, я некоторое время использовал [select @qry], чтобы я мог видеть/отлаживать генерацию инструкции SQL до ее запуска. Ваш код работал как обещал - большое вам спасибо за вашу помощь! –

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

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

3

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

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

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 
0

См this answer

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

2
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 
Смежные вопросы