2010-05-25 64 views
0

在MSSQL中使用PIVOT的每个示例都显示使用此功能的用户可以聚合数据。我想利用这个只是简单的调换行列如何将行转换为列

例如,考虑follwoing数据

SELECT 11826 ID,cast('64 ' as varchar(1000)) as answer,75098 QuestionID,2785 CollectionID into #temp 
insert into #temp SELECT 11827 ID,cast('Security ' as varchar(1000)) as answer,75110 QuestionID,2785 CollectionID 
insert into #temp SELECT 11828 ID,cast('42 ' as varchar(1000)) as answer,75115 QuestionID,2785 CollectionID 
insert into #temp SELECT 11829 ID,cast('3/23/2010 12:01:00 AM ' as varchar(1000)) as answer,75119 QuestionID,2785 CollectionID 
insert into #temp SELECT 11830 ID,cast('3/25/2010 ' as varchar(1000)) as answer,75120 QuestionID,2785 CollectionID 
insert into #temp SELECT 11898 ID,cast('67 ' as varchar(1000)) as answer,75313 QuestionID,2792 CollectionID 
insert into #temp SELECT 11899 ID,cast('True ' as varchar(1000)) as answer,75314 QuestionID,2792 CollectionID 
insert into #temp SELECT 11900 ID,cast('0 ' as varchar(1000)) as answer,75315 QuestionID,2792 CollectionID 
insert into #temp SELECT 11901 ID,cast('[email protected] ' as varchar(1000)) as answer,75316 QuestionID,2792 CollectionID 

结果应该得到类似

CollectionID [AnswerFor75098]  [AnswerFor75110]  [AnswerFor75115]  [AnswerFor75315]... 
2785    64     Security   42     
2792    Null    Null     Null     67 

我一直在尝试与PIVOT,但我不知道这是正确的解决方案。如果是这样,是否有人有我可以使用的提示? 我想我可以在存储过程中公平地做到这一点,但我试图尽可能避免使用游标。

感谢您的帮助

回答

1

您正在寻找的是交叉表查询。如果你知道你寻找的时间提前了问题编号,你可以像这样:

Select CollectionId 
    , Min(Case When Question = 75098 Then Answer End) As AnswerFor75098 
    , Min(Case When Question = 75110 Then Answer End) As AnswerFor75110 
    , Min(Case When Question = 75115 Then Answer End) As AnswerFor75115 
    , Min(Case When Question = 75315 Then Answer End) As AnswerFor75315 
From #Temp 
Group By CollectionId 

但是,如果你想要的是动态地确定基于问题的列,那么你想要的是一个动态交叉并且不能在没有一些烦人的动态SQL的情况下在SQL Server中完成。相反,您应该在中间层或报告工具中执行此操作。

+0

我在那里,过分复杂的事情。我将首先尝试这种方法,然后我会弄糟这个关键点。 – Beta033 2010-05-25 15:45:39

1

一件事,人们往往当他们尝试PIVOT不知道的是,你需要知道你的列并将它们硬编码到查询。这导致我们想,“这真的是最好的方式吗?”

即使使用Microsoft的PIVOT语法,也无法编写基于数据值动态添加列的通用SQL查询。

PIVOT仍然比编写一堆JOIN更方便,所以我建议使用PIVOT(如果您只使用Microsoft SQL Server)。

+0

的Oracle 11g +支持PIVOT和UNPIVOT语法。在我对SQL Server 2005中的PIVOT与CASE的有限比较中,CASE稍微快了一点。我倾向于使用CASE语句,主要是为了便携性问题。 – 2010-05-25 15:32:07

+0

这不能严格地在单个SELECT查询中完成,但是您可以使用具有一个select的存储过程来完成动态执行的动态SQL。事情发生的时候,我今天早上就这么做了,使用了从http://www.sqlprof.com/blogs/sqldev/archive/2008/04/12/pivots-with-dynamic-columns-in-sql-server- 2005-2008.aspx – 2010-05-25 20:02:23

0

我已经做了一个快速的Sql来显示如何使用Pivot与您的示例数据。 我认为它可以改进,以达到你想要的。

Select CollectionId,[75098],[75110],[75113],[75114],[75115] from 
(Select QuestionID ,CollectionId, answer From #temp group by QuestionID,CollectionId, answer) as ST 
    PIVOT (count(QuestionID) for QuestionID in ([75098],[75110],[75113],[75114],[75115]))as PT 
group by CollectionId,[75098],[75110],[75113],[75114],[75115] 

@community,请随时与任何修改建议这个建议