0

2 つのテーブルがあるとします。

Question (Id, Text)
Answer (Value, QuestionId, Guid)

Guidは同じ人物からの回答をグループ化します。

次のような結果を生成するには、クエリが必要です。

'Question 1' | 'Question 2'
4            | 3
1            | NULL
NULL         | 5
2            | 6
9            | NULL

質問のテキストは列ヘッダーに変換され、回答の値は行に表示されます。回答は でグループ化されてGuidいるため、1 行に 1 人の回答があります。特定の質問に回答しなかった場合は、NULL が返されます。

質問の数は異なる場合があります。

サンプル結果の生成に使用されるデータ:

 Question
 Id   | Text
 1    | Question 1
 2    | Question 2

 Answer
 Value | QuestionId | Guid
 4     | 1          | AAA
 3     | 2          | AAA
 1     | 1          | BBB
 5     | 2          | CCC
 2     | 1          | DDD
 6     | 2          | DDD
 9     | 1          | EEE

結果を生成するためのクエリを手伝ってもらえますか?

4

2 に答える 2

3

PIVOT不明な数の質問があるため、これには動的 SQL を使用する必要があります。

DECLARE @colsFinal AS NVARCHAR(MAX),
    @colsPivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @colsFinal = STUFF((SELECT distinct ',' 
                      + QUOTENAME(Id) 
                           + ' as Question_'+ cast(Id as varchar(10))
                    from question
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsPivot = STUFF((SELECT distinct ',' 
                      + QUOTENAME(Id) 
                    from question
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @colsFinal + ' from 
             (
                select questionid, value, guid
                from question q
                left join value v
                  on q.id = v.questionid
            ) x
            pivot 
            (
                min(value)
                for questionid in (' + @colsPivot + ')
            ) p '

execute(@query)

デモで SQL Fiddle を参照してください

既知の数の列がある場合は、値をハードコーディングできますPIVOT( SQL Fiddle With Demoを参照)。

select [1] as Question1, [2] as Question2
from 
(
  select questionid, value, guid
  from question q
  left join value v
    on q.id = v.questionid
) x
pivot
(
  max(value)
  for questionid in ([1], [2])
) p

または、集計関数を使用することもできますCASE( SQL Fiddle With Demoを参照):

select max(case when q.id = 1 then v.value end) Question1,
  max(case when q.id = 2 then v.value end) Question2
from question q
left join value v
  on q.id = v.questionid
group by guid
于 2012-10-04T21:55:34.060 に答える
2

質問番号をハードコーディングしたくない場合は、動的 SQL を使用して質問リストを作成することしかできません。

SQL Server動的PIVOTクエリ?

特定の質問については、そのテキストを知っている場合は、以下のサンプルを参照してください

create table Question(id int, text varchar(100));
insert Question select 1, 'Question 1'
union all select 2, 'The 2nd';
create table Answer(
  value int,
  questionid int,
  guid varchar(10));
insert Answer select
 4     , 1          , 'AAA' union all select
 3     , 2          , 'AAA' union all select
 1     , 1          , 'BBB' union all select
 5     , 2          , 'CCC' union all select
 2     , 1          , 'DDD' union all select
 6     , 2          , 'DDD' union all select
 9     , 1          , 'EEE';
GO
select guid, [Question 1], [The 2nd]
from (
    select guid, text, value
    from Answer A
    join Question Q on A.questionid=q.id) p
pivot (max(value) for text in ([Question 1], [The 2nd])) v
于 2012-10-04T21:53:53.880 に答える