SQL Server 数据库中的动态数据透视

Posted

技术标签:

【中文标题】SQL Server 数据库中的动态数据透视【英文标题】:Dynamic pivot in SQL Server database 【发布时间】:2016-05-18 08:05:42 【问题描述】:

我正在编写一个必须生成数据透视表的查询。现在下面是我的代码。

select *
from
(select [case owner], [time taken(minutes)] from StatusTable) as pivotdata
pivot(
sum([time taken(minutes)])
for [CASE OWNER] in
("XXX", "AAA", "BBB")
) as pivoting

但是我不需要在for-in 中给出行,而是需要动态获取,我在这里看到了一个查询SQL Server dynamic PIVOT query? 并将我的查询修改为

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME([case owner]) 
            FROM StatusTable c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'select *
from
(select [case owner], [time taken(minutes)] from StatusTable) as pivotdata
pivot(
sum([time taken(minutes)])
for [CASE OWNER] in
('+@cols+')
) as pivoting'

execute(@query)

这很好用,但问题是我必须在我的 JDBC 程序中使用这个查询。如果不使用execute(@query),它就不会在我的 SQL Server 中运行。我可以使这个查询类似于第一个查询,以便我可以在我的程序中使用相同的查询吗?

【问题讨论】:

要执行dynamic query/SQL string,您需要EXECUTEEXEC SP_EXECUTESQL 没有其他方法 如果不通过 SP_EXECUTESQL 或 EXECUTE (EXEC) 命令执行@query,则只有 NVARCHAR 类型的字符串变量。 【参考方案1】:

Microsoft 的 SQL Server JDBC 驱动程序 (mssql-jdbc) 支持执行匿名代码块(多个 SQL 语句),因此我们可以只执行相同的 SQL 代码,包括EXECUTE(...) at结束:

String sql = " "
        + "SET NOCOUNT ON; "
        + "DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX); "
        + " "
        + "SET @cols =  "
        + "    STUFF( "
        + "        ( "
        + "            SELECT distinct ',' + QUOTENAME([case owner])  "
        + "            FROM StatusTable c "
        + "            FOR XML PATH(''), TYPE "
        + "        ).value('.', 'NVARCHAR(MAX)'), "
        + "        1, "
        + "        1, "
        + "        ''); "
        + " "
        + "set @query = 'select * "
        + "from "
        + "( "
        + "    select [case owner], [time taken(minutes)] from StatusTable "
        + ") as pivotdata "
        + "pivot( "
        + "    sum([time taken(minutes)]) for [CASE OWNER] in ('+@cols+') "
        + ") as pivoting'; "
        +" "
        + "execute(@query); ";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
// print column headings
for (int i = 1; i <= rsmd.getColumnCount(); i++) 
    System.out.printf("%5s", rsmd.getColumnLabel(i));

System.out.println();
rs.next();
// print column values
for (int i = 1; i <= rsmd.getColumnCount(); i++) 
    System.out.printf("%5s", rs.getString(i));

System.out.println();
/* console output:

   AAA  BBB  XXX
     2   13    1

 */

【讨论】:

以上是关于SQL Server 数据库中的动态数据透视的主要内容,如果未能解决你的问题,请参考以下文章

MS SQL Server 中的动态数据透视

使用 Sql Developer Oracle 的动态数据透视查询

SQL Server - 动态数据透视表 - SQL 注入

SQL Server 中具有动态列的数据透视表

SQL Server 中的动态透视列

SQL Server 中的数据透视表查询