Dan*_*ola 12 sql pivot sql-server-2008
我有一个看起来像这样的表:
Month Site Val
2009-12 Microsoft 10
2009-11 Microsoft 12
2009-10 Microsoft 13
2009-12 Google 20
2009-11 Google 21
2009-10 Google 22
Run Code Online (Sandbox Code Playgroud)
我希望得到一个二维表,为每个网站的月份提供"Val",例如:
Month Microsoft Google
2009-12 10 20
2009-11 12 21
2009-10 13 22
Run Code Online (Sandbox Code Playgroud)
但问题是,我不知道"网站"中可能存在的所有可能值.如果出现新网站,我想在结果表中自动获取新列.
我看到的所有可以执行此操作的代码示例都要求我在查询文本中对"Microsoft和Google"进行硬编码.
我看到一个没有,但它基本上是通过列出站点并在其中生成具有这些列名称的动态查询(连接字符串)来伪装它.
没有办法让SQL Server 2008在没有这样的黑客的情况下做到这一点吗?
注意:我需要能够运行这个作为我从ASP.Net发送的查询,我不能做存储过程或其他类似的东西.
谢谢!
丹尼尔
10多年过去了,同样的问题也出现在我身上。
有没有办法在不知道列名的情况下进行透视?
然后我搜索了一些东西并找到了以下解决方案。我们可以通过使用动态查询来实现这一点。我添加这个是为了对某人有所帮助。
CREATE TABLE TEMP
(
[Month] varchar(50),
[Site] varchar(50),
Val int
)
INSERT INTO TEMP
VALUES ('2009-12', 'Microsoft', 10),
('2009-11', 'Microsoft', 12),
('2009-10', 'Microsoft', 15),
('2009-12', 'Google', 20),
('2009-11', 'Google', 8),
('2009-10', 'Google', 11),
('2009-12', 'Facebook', 13),
('2009-11', 'Facebook', 12),
('2009-10', 'Facebook', 5)
DECLARE @Columns as VARCHAR(MAX)
SELECT @Columns = COALESCE(@Columns + ', ','') + QUOTENAME([Site])
FROM
(SELECT DISTINCT [Site] FROM TEMP) AS B
ORDER BY B.[Site]
DECLARE @SQL as VARCHAR(MAX)
SET @SQL = 'SELECT Month, ' + @Columns + '
FROM
(
select Month,[Site],Val from TEMP
) as PivotData
PIVOT
(
Sum(Val)
FOR [Site] IN (' + @Columns + ')
) AS PivotResult
ORDER BY Month'
EXEC(@SQL);
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我将列值放入字符串中,然后动态地使用它来进行透视。
结果如下:
您链接的示例使用动态SQL.不幸的是,当事先不知道输出列时,没有其他内置的方法可以在SQL Server中进行数据透视.
如果数据不是太大,那么从ASP.NET运行普通行查询并在应用程序代码中执行数据透视可能是最简单的.如果数据非常大,那么在首次查询可能的列值之后,您必须动态生成SQL.
请注意,您实际上不需要编写生成动态SQL的SQL语句; 你可以简单地在ASP.NET中生成SQL,这很可能会更容易.只是不要忘记Site
在生成的查询中放弃它们之前逃避不同的值,并且不要忘记参数化没有数据透视表时通常会出现的SQL语句的任何部分.