如何将行旋转为列

发布于 2024-09-02 11:39:29 字数 1670 浏览 5 评论 0原文

在 MSSQL 中使用 PIVOT 的每个示例都表明人们使用它来聚合数据。我正在尝试利用它来简单地将行转置为列

例如,考虑以下数据

   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 的结果,但我不确定这是正确的解决方案。如果是这样,有人有我可以使用的提示吗? 我想我可以在存储过程中公平地做到这一点,但是,如果可能的话,我试图避免使用游标。

感谢您的帮助

Every example of using PIVOT in MSSQL shows people using this to aggregate data. I'm trying to exploit this to just simply transpose rows to columns

For instance, consider the follwoing data

   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

The results should yield something like

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

I've been experimenting with PIVOT however i'm not sure this is the correct solution. If so, does anybody have a hint i could use?
I think i can probably do this in a stored procedure fairly however, i'm trying to avoid using cursors if possible.

Thanks for the help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

帝王念 2024-09-09 11:39:29

您正在寻找的是交叉表查询。如果您提前知道要查找的问题编号,则可以这样做:

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。相反,您应该在中间层或报告工具中执行此操作。

What you are seeking is a crosstab query. If you know the question numbers you seek ahead of time, you can do it like so:

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

However, if what you want is to dynamically determine the columns based on questions, then what you want is a dynamic crosstab and that cannot be done in SQL Server without some fugly dynamic SQL. Instead, you should do this in the middle-tier or in a reporting tool.

羅雙樹 2024-09-09 11:39:29

人们在尝试 PIVOT 时通常没有意识到的一件事是,您需要了解您的列并将它们硬编码到查询中。这让我们思考:“这真的是最好的方法吗?”

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

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

One thing that people often don't realize when they try PIVOT is that you need to know your columns and hard-code them into the query. This leads us to think, "is this really the best way?"

You can't write a general-purpose SQL query that adds columns dynamically based on data values, even when you use Microsoft's PIVOT syntax.

PIVOT is still a bit more convenient than writing a bunch of JOINs, so I'd suggest going with PIVOT (if you use Microsoft SQL Server exclusively).

腹黑女流氓 2024-09-09 11:39:29

我已经完成了一个快速 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,请随时对此建议提出任何修改建议

I have done a quick Sql to show how to use Pivot with your sample data.
I think it can be improved to acheive what you want.

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, please feel free to suggest any amendments to this suggestion

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文