如何将数据行转换为列?

时间:2010-01-15 08:00:59

标签: sql sql-server-2005 pivot

我有一个表tblUser,列

userId,firstName,LastName,Mobile,.......,QuestionID

我有另一张名为tblResults的表,其中包含这些列

questionID,Question,choiceID,choice,.........

tblUser
-----------------------------------------------------------------------------
userID -  FirstName- LstName -Mobile  ...     ...     ... -  QuestionID -  ChiceID
-----------------------------------------------------------------------------
001   -   xx     -     yy   -   03212          -                   01        01 
001   -   xx     -     yy   -   03212          -                   02        02 
002   -   xxx     -    yyy  -   03425         -                    01        02 
002   -   xxx     -    yyy  -   03425        -                     02        01  
003   -   xxxx    -    yyyy  -  03429         -                    03        02 
003   -   xxxx   -     yyyy  -  03429          -                   03        01 
------------------------------------------------------------------------------

tblResults
---------------------------------------------------------------------
QuestionID   Question       ChoiceID       Chice    ....     ....            
---------------------------------------------------------------------
01        -    **Are you**   -  01   -   Male
01        -    **Areyou**    -  02    -  Female
02        -    **From**     -   01   -   xxxxx
02        -    **FROM**     -   02    -  yyyyy  
---------------------------------------------------------------------

我想得到如下表所示的结果

-------------------------------------------------------------------------------
UserID FirstName LastName  Mobile  **Areyou**   **From**
-------------------------------------------------------------------------------
001    -   xx     -  yy     -   03212  -  Male  -  yyyyy
002    -   xxx    -  yyy    -   03425   - Female - xxxxx
003    -   xxxx   -  yyyy   -   03429  -  Female -  xxxxx        

3 个答案:

答案 0 :(得分:0)

您可以为每个问题获得唯一用户的相应选择,并为每个问题加入tbl结果表一次:

select
  u.userID, u.FirstName, u.LastName, u.Mobile,
  q1.Choice as Areyou,
  q2.Choice as [From]
from (
  select userID, FirstName, LastName, Mobile,
  sum(case QuestionId when '01' then ChoiseId else 0 end) as ChoiseId1,
  sum(case QuestionId when '02' then ChoiseId else 0 end) as ChoiseId2
  from tblUser
) as u
inner join tblResults as q1 on q1.QuestionID = '01' and q1.ChoiseID = u.ChoiseId1
inner join tblResults as q2 on q2.QuestionID = '02' and q2.ChoiseID = u.ChoiseId2

答案 1 :(得分:0)

从根本上说,我们可以为每个问题创建一个表t(UserID,ChoiceID),然后在内部连接所有这些表。然后我们得到了(UserID,ChoiceID_for_Question_1,ChoiceID_for_Question_2,...)。再添加用户信息,我们得到了理想的结果。


select t1.UserID, t1.FirstName, t1.LastName, t1.Mobile, t1.Choice, t2.Choice
from 
  (select u.UserID, u.FirstName, u.LastName, u.Mobile, r.Choice
  from tblUser u, tblResults r 
  where u.questionID = '01' and u.QuestionID=r.QuestionID and u.ChoiceID = r.ChoiceID) t1
inner join 
  (select u.UserID UserID, r.Choice
  from tblUser u, tblResults r 
  where u.questionID = '02' and u.QuestionID=r.QuestionID and u.ChoiceID = r.ChoiceID) t2
/* 
inner join
  (...) t3
*/
on t1.UserID = t2.UserID /* and t2.UserID = t3.UserID */

答案 2 :(得分:0)

您可以使用PIVOT生成所需的结果。有两种方法可以是对列进行硬编码的Static Pivot,也可以是在运行时获取列列表的Dynamic Pivot。

静态数据透视:(请参阅SQL Fiddle With Demo

create table tblUser
(
    userid int,
    fname varchar(10),
    lname varchar(10),
    mobile int,
    questionid int,
    choiceid int
) 
insert into tblUser values (001, 'xx', 'yy', 03212, 01, 01)
insert into tblUser values (001, 'xx', 'yy', 03212, 02, 02)
insert into tblUser values (002, 'xxx', 'yyy', 03425, 01, 02)
insert into tblUser values (002, 'xxx', 'yyy', 03425, 02, 01)
insert into tblUser values (003, 'xxxx', 'yyyy', 03429, 03, 02)
insert into tblUser values (003, 'xxxx', 'yyyy', 03429, 03, 01)

create table tblResults
(
    questionid int,
    question varchar(10),
    choiceid int,
    choice varchar(10)
)
insert into tblresults values (01, 'Are you', 01, 'Male')
insert into tblresults values (01, 'Are you', 02, 'Female')
insert into tblresults values (02, 'From', 01, 'xxxxx')
insert into tblresults values (02, 'From', 02, 'yyyyy')

select *
from 
(
    select u.userid,
        u.fname,
        u.lname,
        u.mobile,
        r.question,
        r.choice
    from tbluser u
    left join tblresults r
        on u.questionid = r.questionid
        and u.choiceid = r.choiceid
) x
pivot
(
    min(choice)
    for question in([are you], [from])
) p

动态数据透视:(请参阅SQL Fiddle with Demo

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.question) 
            FROM tblresults c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT userid, fname, lname, mobile, ' + @cols + ' from 
            (
                select u.userid,
                    u.fname,
                    u.lname,
                    u.mobile,
                    r.question,
                    r.choice
                from tbluser u
                left join tblresults r
                    on u.questionid = r.questionid
                    and u.choiceid = r.choiceid
           ) x
            pivot 
            (
                min(choice)
                for question in (' + @cols + ')
            ) p '


execute(@query)

两者都会产生相同的结果。