【问题标题】:SQL Server 2012 dynamic pivot - concatenation for cross tabSQL Server 2012 动态数据透视 - 交叉表的连接
【发布时间】:2016-11-11 06:40:42
【问题描述】:

我可以使用串联作为动态数据透视表中的交叉表变量吗?

我正在尝试生成交易值的交叉表,其中列标题是 [yyyy-mm] 基于 [交易日期] 日期字段的日期顺序。

这是数据:-

 RW_Ref     ,Transaction_Date  ,Transaction_Type ,Transaction_Value ,Batch_Number ,Month
     1    ,  03/09/2009              ,11              ,30               ,999   
     1     , 05/10/2009              ,11              ,25               ,999 
     1     , 11/10/2009              ,11              ,15               ,999
     1     , 15/11/2009              ,11              ,40               ,999
     1     , 03/12/2009              ,11              ,30               ,999   
     2     , 05/10/2009              ,11              ,60               ,999 
     2     , 11/11/2009              ,11              ,70               ,999
     2     , 01/12/2009              ,11              ,60               ,999
     2     , 03/12/2009              ,11              ,15               ,999   
     3     , 05/11/2009              ,11              ,25               ,999
     3     , 06/11/2009              ,11              ,35               ,999
     3     , 07/11/2009              ,11              ,60               ,999

这就是我想要找回的:-

Transaction_Type,Batch_Number,[2009-09],[2009-10],[2009-11],[2009-12]
11              ,999         ,30       ,40       ,40       ,30       
11              ,999         ,         ,60       ,70       ,75       
11              ,999         ,         ,         ,120      ,         

这是我目前得到的代码:-

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

select      @cols = STUFF((SELECT distinct ', ' 
        + QUOTENAME(CONCAT(datepart(yyyy,[Transaction_Date]) , '-', RIGHT('00' + CONVERT(NVARCHAR(2), datepart(M,[Transaction_Date])), 2)))
                from [TX].[dbo].[Transactions] ORDER by 1
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
       ,1,1,'')

set @query = 
'SELECT [RW_Ref], [Transaction_Type], [Transaction_Value], [Batch_Number], ' 
         + @cols 
         + ' ' 
         +'FROM [TX].[dbo].[Transactions] 
               PIVOT (
                   SUM([Transaction_Value])
              FOR
                   CONCAT(
                   datepart(yyyy,[Transaction_Date]), ' 
                   + QUOTENAME('-','''') 
                       + ', RIGHT(' + QUOTENAME('00','''') + ' + CONVERT(NVARCHAR(2), datepart(M,[Transaction_Date])), 2))
               ) p '
 print @query

 execute(@query)

Print @Query 产生这个:-

SELECT [RW_Ref], [Transaction_Type], [Transaction_Value], [Batch_Number],  [2009-09], [2009-10], [2009-11], [2009-12], [2016-07] FROM [TX].[dbo].[Transactions] 
PIVOT (
SUM([Transaction_Value]) 
FOR
CONCAT(
datepart(yyyy,[Transaction_Date]), '-', 
RIGHT('00' + CONVERT(NVARCHAR(2), datepart(M,[Transaction_Date])), 2))
) p 

但这会生成一条消息 消息 102,第 15 级,状态 1,第 5 行 '(' 附近的语法不正确。 第 5 行是 CONCAT( 我认为。我可以使用 Concat 函数以这种方式生成列标题还是我必须只使用记录(这意味着我需要将该字段添加为我宁愿的列不行,这不是我的桌子)

谢谢!

【问题讨论】:

  • 查看docs 建议 SQL Server 在 FOR 之后需要一个命名列,在 IN 之后需要一个透视列列表。这不能直接参数化。您需要动态 SQL 来计算这些,因为它填充了 @query var。
  • 我认为 PIVOT 的语法应该是 PIVOT(SUM([...]) FOR IN (value1, value2,...)) p。上面的@Query 字符串似乎违反了这一点。

标签: sql-server tsql crosstab


【解决方案1】:

您是否尝试过以下代码? 编辑:您在选择和语句中都需要原始日期值。您必须修改查询的“select @cols = ...”部分以将原始值(删除列中的 datepart 内容)作为列名返回,并根据需要为它们设置别名。 IN 运算符需要完整的值。

    set @query = 
'SELECT [RW_Ref], [Transaction_Type], [Batch_Number], ' 
         + @cols 
         + ' ' 
         +'FROM [TX].[dbo].[Transactions] 
               PIVOT (
                   SUM([Transaction_Value])
              FOR

                   [Transaction_Date] IN ( ' 
                   + @cols + ')
               ) p '

请让我知道它是否有效。请参阅下面的示例,您可以在 TSQL2012 示例数据库上运行该示例,它应该可以帮助您了解数据透视语句的工作原理。

select shipperid, [2006-07-29 00:00:00.000] as '2006/07', [2006-08-12 00:00:00.000] as '2006/08'
from sales.orders
pivot (sum (freight) for shippeddate in ([2006-07-29 00:00:00.000], [2006-08-12 00:00:00.000])) as p

【讨论】:

  • 谢谢。那行得通:o)但是它会为每天创建一个包含一列的表,这是我试图避免的。至少我现在对动态枢轴的了解足以知道我不能为此使用它,我将不得不使用另一种方法。
  • 我认为您可以尝试编写一个子查询,将交易按月分组,然后将其用于透视。
猜你喜欢
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 2017-07-28
  • 2013-02-09
  • 1970-01-01
  • 2015-04-15
  • 2013-06-09
  • 2020-04-10
相关资源
最近更新 更多