在 SQL Server 2008 中使用 PIVOT
Posted
技术标签:
【中文标题】在 SQL Server 2008 中使用 PIVOT【英文标题】:Using PIVOT in SQL Server 2008 【发布时间】:2010-12-13 06:06:37 【问题描述】:假设我有一些数据,在 SQL Server 2008 表或 [table] 类型的变量中:
author_id review_id question_id answer_id
88540 99001 1 719
88540 99001 2 720
88540 99001 3 721
88540 99001 4 722
88540 99001 5 723
36414 24336 1 302
36414 24336 2 303
36414 24336 3 304
36414 24336 4 305
36414 24336 5 306
我想将数据检索为如下所示的结果集:
author_id review_id 1 2 3 4 5
88540 99001 719 720 721 722 723
36414 24336 302 303 304 305 306
我怀疑 PIVOT 运算符是我需要的(无论如何,根据this post),但我不知道如何开始,尤其是当 question_id 行数表可以变化。在上面的示例中,它是 5,但在另一个查询中,该表可能会填充 7 个不同的问题。
【问题讨论】:
【参考方案1】:实际上,您最好在客户端中执行此操作。假设您正在使用 Reporting Services,根据您的第一个结果集获取数据并使用矩阵显示它,其中 author_id 和 review_id 在行组中,question_id 在列组中,MAX(answer_id) 在中间。
查询是可行的,但您现在需要动态 SQL。
...类似:
DECLARE @QuestionList nvarchar(max);
SELECT @QuestionList = STUFF(
(SELECT ', ' + quotename(question_id)
FROM YourTable
GROUP BY question_id
ORDER BY question_id
FOR XML PATH(''))
, 1, 2, '');
DECLARE @qry nvarchar(max);
SET @qry = '
SELECT author_id, review_id, ' + @QuestionList +
FROM (SELECT author_id, review_id, question_id, answer_id
FROM YourTable
)
PIVOT
(MAX(AnswerID) FOR question_id IN (' + @QuestionList + ')) pvt
ORDER BY author_id, review_id;';
exec sp_executesql @qry;
【讨论】:
这似乎是我需要的。我会试一试并报告——谢谢! 请记住子查询。如果您只使用“SELECT * FROM YourTable”,那么所涉及的任何其他列都会影响 PIVOT 函数提供的隐式分组。如果您有任何错误,请注释掉exec
行,将其替换为 select @qry
我不再使用 [SELECT *] ——我总是明确说明我访问的列——所以这不会成为问题。是的,我使用 [select @qry] 有一段时间了,这样我就可以在生成 SQL 语句运行之前查看/调试它。您的代码按承诺运行 - 非常感谢您的帮助!【参考方案2】:
Here你有很好的例子和解释。
你的情况是这样的:
SELECT author_id, review_id, [1], [2], [3], [4], [5]
FROM
(
SELECT author_id, review_id, question_id, answer_id
FROM the_table
) up
PIVOT (MAX(answer_id) FOR question_id IN ([1],[2],[3],[4],[5])) AS pvt
【讨论】:
【参考方案3】:SELECT author_id, review_id, [1], [2], [3], [4], [5]
FROM
(
SELECT author_id, review_id, question_id, answer_id
FROM the_table
) up
PIVOT (MAX(answer_id) FOR
【讨论】:
【参考方案4】:select *
from @t pivot
(
max(answer_id) for question_id in ([1],[2],[3],[4],[5])
) pivotT
改变列表([1]、[2]、[3]、[4]、[5])的唯一方法是在字符串中(动态)构建此查询,然后执行它。
【讨论】:
【参考方案5】:见this answer
基本上,您预先检查数据以获取列,然后使用动态数据透视表动态生成 SQL。真的没有非动态的方式,因为你要返回的集合中列的定义是不固定的。
【讨论】:
以上是关于在 SQL Server 2008 中使用 PIVOT的主要内容,如果未能解决你的问题,请参考以下文章
Query (SQL Server 2008 Express) 在 SQL Server Management Studio 中有效,但在 Delphi 中使用 ADODB 无效
在 sql server 2008 中使用 unicode 文本
安装SQL SERVER 2008,出现“查找sql server 2008安装媒体”的问题