4

次のような 2 つのテーブルAnswersUsersがあります。

Answers (AnswerID, QuestionNumber, Answer, UserID)
Users (UserID, FirstName, LastName)

次のようなレポートを返すために実行できる SQL クエリは次のとおりです。

ここに画像の説明を入力

4

2 に答える 2

3

関数を使用して、PIVOTこのデータを変換できます。(Firstname/Lastname) をヘッダーとして使用するのはかなり珍しいようですがName、それが必要な場合は、次を使用できます。

select *
from
(
  select a.questionnumber,
    u.firstname +' '+ u.lastname as Name,
    a.answer
  from answers a
  left join users u
    on a.userid = u.userid
) src
pivot
(
  max(answer)
  for name in ([John Smith], [Bob Jones])
) piv;

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

結果:

| QUESTIONNUMBER | JOHN SMITH | BOB JONES |
-------------------------------------------
|              1 |       blah |      test |
|              2 |      hsdfk |    (null) |

Question Numbers次のように、ヘッダーとして、その下に回答が表示されるようにする必要があると思います。

select *
from
(
  select 'QuestionNumber'+cast(a.questionnumber as varchar(10)) questionnumber,
    u.firstname +' '+ u.lastname as Name,
    a.answer
  from answers a
  left join users u
    on a.userid = u.userid
) src
pivot
(
  max(answer)
  for questionnumber in ([QuestionNumber1], [QuestionNumber2])
) piv;

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

結果:

|       NAME | QUESTIONNUMBER1 | QUESTIONNUMBER2 |
--------------------------------------------------
|  Bob Jones |            test |          (null) |
| John Smith |            blah |           hsdfk |

上記の回答は、変換するアイテムの数がわかっている場合にうまく機能します。ただし、番号が不明な場合はPIVOT、データに対して動的 SQL を使用できます。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('QuestionNumber'+cast(questionnumber as varchar(10))) 
                    from answers
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT Name, ' + @cols + ' from 
             (
              select ''QuestionNumber''+cast(a.questionnumber as varchar(10)) questionnumber,
                u.firstname +'' ''+ u.lastname as Name,
                a.answer
              from answers a
              left join users u
                on a.userid = u.userid
            ) x
            pivot 
            (
                max(answer)
                for questionnumber in (' + @cols + ')
            ) p '

execute(@query)

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

結果:

|       NAME | QUESTIONNUMBER1 | QUESTIONNUMBER2 |
--------------------------------------------------
|  Bob Jones |            test |          (null) |
| John Smith |            blah |           hsdfk |
于 2012-11-29T12:02:34.663 に答える
0

これはクロス集計クエリと呼ばれます - それらを生成する方法の例はたくさんあります。例えば:

http://www.simple-talk.com/sql/t-sql-programming/creating-cross-tab-queries-and-pivot-tables-in-sql/

編集

ピボットを使用する@Bluefleetがおそらく最良の答えです。単純なクロス集計を使用するには、データの形状のいくつかの側面を事前に知っておく必要がある場合があるため、列は本質的にハードコードされています-列が安定したセットである場合、次のように動作するはずです:

declare @Answers table (AnswerID int, QuestionNumber int , Answer int , UserID int)
declare @Users table (UserID int , FirstName varchar(10), LastName varchar(10))
declare @Questions table (QuestionNumber int, QuestionName varchar(10))

insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (1, 1, 10, 1)
insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (2, 2, 20, 1)
insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (3, 3, 30, 2)
insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (1, 1, 40, 2)
insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (2, 2, 50, 2)
insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (3, 3, 60, 3)
insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (1, 1, 70, 3)
insert into @Answers (AnswerID, QuestionNumber, Answer, UserID) values (2, 2, 80, 3)

insert into @Users (UserID, FirstName, LastName) values (1, 'Tom', 'Smith')
insert into @Users (UserID, FirstName, LastName) values (2, 'Dick', 'Brown')
insert into @Users (UserID, FirstName, LastName) values (3, 'Harry', 'Robinson')

insert into @Questions (QuestionNumber, QuestionName) values (1, 'Question 1')
insert into @Questions (QuestionNumber, QuestionName) values (2, 'Question 2')
insert into @Questions (QuestionNumber, QuestionName) values (3, 'Question 3')

select 
    QuestionName, MAX(User1) as 'Tom Smith', MAX(User2) as 'Dick Brown', MAX(User3) as 'Harry Robinson'
from 
(
select 
    q.QuestionName,
    (case when a.UserID=1 then Answer else null end) as 'User1',
    (case when a.UserID=2 then Answer else null end) as 'User2',
    (case when a.UserID=3 then Answer else null end) as 'User3'
from @Answers a
join @Users u on u.UserID = a.UserID
join @Questions q on q.QuestionNumber = a.QuestionNumber
) as combined
group by QuestionName



QuestionName Tom Smith   Dick Brown  Harry Robinson
------------ ----------- ----------- --------------
Question 1   10          40          70
Question 2   20          50          80
Question 3   NULL        30          60
于 2012-11-29T11:51:46.707 に答える