【问题标题】:Dynamic pivoting SQL Server 2012动态透视 SQL Server 2012
【发布时间】:2025-02-11 15:15:01
【问题描述】:

我正在尝试在 SQL Server 2012 中运行我的第一个动态数据透视。

我用于动态旋转的#temp 表如下所示。

YearMonth   Agreement nr    Discount
------------------------------------
201303         123            1
201303          12            0
201304           1            0

我正在运行这段代码,但它不起作用:

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)

--Get distinct values of the PIVOT Column 
SELECT @ColumnName = ISNULL(@ColumnName + ',', '') + QUOTENAME(YearMonth )
FROM (SELECT DISTINCT YearMonth FROM #FINAL) AS Courses

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
  N'SELECT [Agreement nr],YearMonth , ' + @ColumnName + '
    FROM #FINAL
    PIVOT(
            COUNT(agreement nr) 
          FOR YearMonth IN (' + @ColumnName + ') AS PVTTable'
--Execute the Dynamic Pivot Query

EXECUTE  @DynamicPivotQuery;

我得到的错误信息是

FOR YearMonth IN ([201403]) AS PVTTable' 不是有效标识符。

我在这里错过了什么?

【问题讨论】:

    标签: sql sql-server-2012 dynamic-pivot


    【解决方案1】:

    错误的原因是您在为 Pivot 设置别名之前缺少括号。不仅如此,您的支点还相当低效。

    您应该为您的数据透视表中的源表选择所需的内容,否则它可能会运行很长时间并产生大量返回空值的行。

    以下是固定的,希望更有效:

    DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
    DECLARE @ColumnName AS NVARCHAR(MAX)
    
    --Get distinct values of the PIVOT Column 
    SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
           + QUOTENAME(YearMonth )
    FROM (SELECT DISTINCT YearMonth FROM #FINAL) AS Courses
    
    --Prepare the PIVOT query using the dynamic 
    SET @DynamicPivotQuery = 
      N'SELECT ' + @ColumnName + '
        FROM (Select [Agreement nr], YearMonth from #FINAL) src
        PIVOT(
                COUNT([Agreement nr]) 
              FOR YearMonth IN (' + @ColumnName + ')) AS PVTTable'
    --Execute the Dynamic Pivot Query
    
    EXECUTE sp_executesql @DynamicPivotQuery;
    

    【讨论】:

    • 我尝试了解决方案,但它抛出了一个错误: COUNT(Agreement nr) FOR YearMonth IN ([201503],[201506],[201504],[201505])) AS PVTTable' is not a有效的标识符。由于我们正在执行 COUNT 而不是包含 YearMonth 的 GROUP BY,因此是否需要 GROUP BY?
    • 尝试将“Agreement nr”也放在方括号中:[Agreement nr]
    • 有趣。我把括号放在它周围,它仍然抛出相同的错误:Msg 203, Level 16, State 2, Line 20 The name 'SELECT [Agreement nr],YearMonth, [201503],[201506],[201504],[201505 ] FROM (Select [Agreement nr], YearMonth from #tester) src PIVOT( COUNT([Agreement nr]) FOR YearMonthIN ([201503],[201506],[201504],[201505])) AS PVTTable' 不是有效的标识符。
    • 您是否尝试过正常运行语句并在@ColumnName 值中进行硬编码?
    • 好的,我知道这里发生了什么。您需要 sp_executesql 来执行该语句。您也不能在选择中有协议 nr 或 YearMonth,因为您将 YearMonth 设置为列,因此您也不能使其成为行,并且您还使用协议 nr 的计数填充列,因此不能是行任何一个。有道理?我已经更新了上面的代码以反映这一点
    【解决方案2】:

    您忘记关闭枢轴。

    PIVOT(
            COUNT(Kundavtalid) 
            FOR YearMonth IN (' + @ColumnName + ') 
         ) AS PVTTable' -- here you miss pathernesis
    

    【讨论】:

      【解决方案3】:

      你少了一个括号

      SET @DynamicPivotQuery = 
        N'SELECT [Agreement nr],YearMonth , ' + @ColumnName + '
          FROM #FINAL
          PIVOT(
                  COUNT([agreement nr]) 
                FOR YearMonth IN (' + @ColumnName + ')) AS PVTTable'
      --Execute the Dynamic Pivot Query
      

      【讨论】: