SQL Server 转置(可能是转置?)多行到一列
Posted
技术标签:
【中文标题】SQL Server 转置(可能是转置?)多行到一列【英文标题】:SQL Server Transpose (maybe pivot?) multiple rows into one column 【发布时间】:2013-04-15 20:20:26 【问题描述】:我的情况是这样的:
我进行了一项调查,有 400 名用户(行)回答了 76 个问题(列)。这些用户在数据库中已经有一个 ID。我创建了一个表格,其中包含每个公司的问题,每个问题都有自己的 ID。所以现在我需要将问题 ID 与每个用户 ID 的答案结合起来。
当我导入时,列标题需要是:
User ID | Question ID | Answer
xxxxxxx | xxxxxxxxxxxxx | xxxxxxxxxx
代替:
User ID | Question ID 1 | Question ID 2 | Question ID 3 | etc...
xxxxxx | xxxxx | xxxxx | xxxxx | ...
感谢您的任何帮助,谢谢。
【问题讨论】:
您是否尝试过将其编写为数据透视查询? 您提到导入答案;你已经这样做了吗?如果不是,为什么不在加载到数据库之前转置数据。使用 Excel 之类的东西很容易做到。 到目前为止,这就是我一直在做的事情,但是用户太多了,我需要永远将用户 ID 分配给答案。我一直在寻找一种通过数据透视表执行此操作的方法,但还无法移除层次结构。 【参考方案1】:听起来您想取消透视数据。根据您的 SQL Server 版本,有多种方法可以完成此操作。
如果您使用的是 SQL Server 2005+,则可以使用 UNPIVOT 函数将列转换为行:
select userid, questionid, answer
from yourtable
unpivot
(
answer
for questionId in (QuestionId1, QuestionId2)
) unpiv;
如果您使用的是 SQL Server 2008+,则可以使用 UNPIVOT 函数,但也可以使用 CROSS APPLY 和 VALUES 将数据从列转换为行:
select t.userid, c.questionid, c.answer
from yourtable t
cross apply
(
values
('QuestionId1', QuestionId1),
('QuestionId2', QuestionId2),
...
) c (questionId, answer);
如果您有未知数量的列需要转换为行,那么您可以使用动态 SQL 来获取结果:
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name != 'userid'
for xml path('')), 1, 1, '')
set @query
= 'select userid, questionid, answer
from yourtable
unpivot
(
answer
for questionid in ('+ @colsunpivot +')
) u'
exec(@query);
附带说明,当您执行这种类型的转换时,被转换为行的列的数据必须是相同的数据类型。例如,如果 Question1 和 Question2 是不同的数据类型,那么您需要在 unpivot 之前转换它们,类似于:
select userid, questionid, answer
from
(
select userid,
cast(questionid1 as varchar(10)) questionid1,
cast(questionid2 as varchar(10)) questionid2
from yourtable
) src
unpivot
(
answer
for questionId in (QuestionId1, QuestionId2)
) unpiv;
【讨论】:
【参考方案2】:您可以在 MSSQL 2005 或更高版本中使用 unpivot:
SELECT [User ID], [Question ID], [Question Reponse]
FROM
(SELECT [User ID], [Question 1], [Question 2]
FROM pvt) p
UNPIVOT
([Question Reponse] FOR [Question ID] IN
([Question 1], [Question 2])
)AS unpvt;
来自: [用户 ID] 整数 ,[问题1] VARCHAR(100) ,[问题2] VARCHAR(100)
结果:
| USER ID | QUESTION ID | QUESTION REPONSE |
--------------------------------------------
| 1 | Question 1 | Blah |
| 1 | Question 2 | BlahBlah |
| 2 | Question 1 | MoreBlah |
| 3 | Question 1 | No Response |
| 3 | Question 2 | Else |
SQL Fiddle
【讨论】:
以上是关于SQL Server 转置(可能是转置?)多行到一列的主要内容,如果未能解决你的问题,请参考以下文章