【问题标题】:Transpose / Pivot Rows to Columns in SQL Server在 SQL Server 中将行转置/透视到列
【发布时间】:2014-04-18 17:36:17
【问题描述】:

我有三个表 - 第一个包含具有唯一 ID 的问题

QID     | Question  
------------------  
1       | Question 1  
2       | Question 2  
3       | Question 3  
4       | Question 4  
5       | Question 5  

第二个包含这些问题的答案,第一个表中的唯一 ID,然后是将答案链接在一起的记录的 ID

QID     | Answer | Parent
-------------------------
1       | Yes    | 123
2       | No     | 123  
3       | No     | 123  
4       | Yes    | 123  
5       | Yes    | 123
1       | No     | 124
2       | Yes    | 124  
3       | No     | 124  
4       | No     | 124  
5       | No     | 124

第三个包含有关父级的其他信息

Parent     |      Parent Title
----------------------------------------
123        |      Questionnaire Sample 1
124        |      Questionnaire Sample 2

理想情况下,我想创建一个视图,将数据转置或旋转成更可用的格式,我的想法是:

Parent     | Question 1     | Question 2     | Question 3     | Question 4     | Question 5
123        | Yes            | No             | No             | Yes            | Yes
124        | No             | Yes            | No             | No             | No

我在这里发现了几个我一直在使用的非常好的线程:

Simple way to transpose columns and rows in Sql?

T-SQL Pivot/Unpivot(Transpose) Column Headers Needed as Data Rows

还有一个:

Transpose rows into columns in SQL Server 2008 R2

我从中提取了以下内容:

SELECT [First_Set], [Second_Set]
FROM
(
  SELECT B.ColumnName, A.Value
    , row_number() over(partition by a.Table2ID
                    order by a.Value) seq
  FROM Table_1 AS A 
  INNER JOIN Table_2 AS B 
    ON A.Table2ID = B.ID
) AS P
PIVOT
(
  min(P.Value)
  for P.ColumnName in ([First_Set], [Second_Set])
) AS PIV;

然后我将其修改为:

SELECT [PARENT], [QUESTION], [ANSWER]
FROM
(
  SELECT B.PARENT_TITLE, C.QUESTION, A.ANSWER
    , row_number() over(partition by a.PARENT
                        order by a.PARENT) seq
  FROM answerTable AS A 
  INNER JOIN parentTable AS B 
    ON A.PARENT = B.PARENT
  INNER JOIN questionTable AS C 
    ON A.QID = C.QID    
) AS P
PIVOT
(
  min(P.RESULT)
  for P.PARENT in ([PARENT], [QUESTION], [ANSWER])
) AS PIV;

返回但仍然不是我需要的。

创建新表格对我来说是不可行的,所以理想情况下我在这里寻找一种动态方法,它用于报告,所以在我看来视图是最简单/最好的,但我愿意接受建议。

谢谢。

【问题讨论】:

标签: sql sql-server transpose


【解决方案1】:

这里是如何动态地做到这一点:

create table #t1(QID int, Question char(10))
insert #t1 values
(1, 'Question 1'),  
(2, 'Question 2'),  
(3, 'Question 3'),  
(4, 'Question 4'),  
(5, 'Question 5')  

create table #t2 (QID int, Answer char(3), Parent int)
insert #t2 values 
(1,        'Yes',    123),
(2,        'No ',    123),  
(3,        'No ',    123),  
(4,        'Yes',    123),  
(5,        'Yes',    123),
(1,        'No ',    124),
(2,        'Yes',    124),  
(3,        'No ',    124),  
(4,        'No ',    124),  
(5,        'No ',    124)

declare @collist nvarchar(max)
SET @collist = stuff((select distinct ',' + QUOTENAME(Question) 
            FROM #t1 -- your table here
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
select @collist

declare @q nvarchar(max)
set @q = '
select * 
from (
    select 
    Question, Answer, Parent
        from (
        select #t1.*, #t2.Answer, #t2.parent
        from #t1
        inner join #t2 on #t1.QID = #t2.QID
    ) as x
) as source
pivot (
    max(Answer)
    for Question in (' + @collist + ')
) as pvt
'

exec (@q)

【讨论】:

  • 哇!好的,那太棒了 - 我能够将我的真实表名放入并为我获取工作和返回数据。谢谢!我能把它构建成一个视图吗?到目前为止,我只完成了基本的视图构建...我的视图可以每次都动态构建临时表吗?
  • 不,您不能由此创建 wiev。您必须将此应用于每个查询。
  • 我可以将#t1 / #t2 分成单独的 ctes 吗?
  • 它们在两个单独的选择语句中使用,其中一个在动态范围内,所以你不能
  • @dean - 使用for xml path 比我用来创建列列表的代码有什么优势吗?我想知道为什么人们使用 xml 路径。 select @pivotList = @pivotList + '[' + Question + '],' from Questions set @pivotList = SUBSTRING(@pivotList, 0, LEN(@pivotList))
【解决方案2】:

解决问题的另一种方式 -

declare @dynamicSQL varchar(max) = ''
declare @pivotList varchar(max) = ''
declare @uniqueQuestions table ([Question] varchar(50) )
insert into @uniqueQuestions
select distinct [Question] from Questions 
select @pivotList = @pivotList + '[' + Question + '],'  from @uniqueQuestions
set @pivotList = SUBSTRING(@pivotList, 0, LEN(@pivotList))
set @dynamicSQL = 
'select *
from
(
select Parent, Question, Answer
from Questions as q
left join Answers as a
on q.QID = a.QID
) as src
pivot(
max(answer)
for Question in (' + @pivotList + ')' + 
')as pvt'
exec(@dynamicSQL)

感谢这篇文章让这一切成为现实 - Convert multiple rows into one with comma as separator

【讨论】:

  • 我的表格与@dean 的表格有何关联 - 问题 = #t1。答案 = #t2。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
相关资源
最近更新 更多