水平查询返回列

时间:2013-08-02 20:06:50

标签: sql sql-server pivot

我在SQL Server中有一个表,它存储了我们网站上的调查问题和答案列表。这是一个非常标准的布局,这是它如何存储完成的调查:

Name          Question                        Answer
James Smith   What is your address?           23 Duck Ln.
James Smith   How old are you?                48
James Smith   Do you have a job?              yes
Sarah Murphy  What is your address?           44 West St.
Sarah Murphy  How old are you?                23
Sarah Murphy  Do you have a job?              no
Jack Western  What is your address?           PO Box 17
Jack Western  Do you have a job?              yes

正如您所看到的,一旦完成一些调查,很难读取数据。我需要水平返回值,每个人只有一行,第一列包含人名,其他每行包含一个问题作为标题,以及其下的答案。以下是查询应如何返回值:

Name          What is your address?    How old are you?    Do you have a job?
James Smith   23 Duck Ln.              48                  yes
Sarah Murphy  44 West St.              23                  no
Jack Western  PO Box 17                                    yes

这可能吗?顺便说一下,我只发布了一些问题 - 如果在网站上提出10个以上的问题,它会变得更大。

感谢您的帮助!

编辑:

请不要关注是否应该在应用程序层中解析记录。我最终想要使用R中的输出,它甚至不是为处理大型数据集而设计的。

1 个答案:

答案 0 :(得分:7)

如果要在SQL中执行此操作,因为您使用的是SQL Server,可以使用PIVOT函数将数据从行转换为列:

select name,
  [What is your address?], 
  [How old are you?], 
  [Do you have a job?]
from yourtable
pivot
(
  max(answer)
  for question in ([What is your address?], [How old are you?], [Do you have a job?])
) piv;

请参阅SQL Fiddle with Demo

如果您有未知值,则可以使用动态SQL来获取解决方案:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Question) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT name, ' + @cols + ' 
             from yourtable
            pivot 
            (
                max(answer)
                for Question in (' + @cols + ')
            ) p '

execute sp_executesql @query;

请参阅SQL Fiddle with Demo