【问题标题】:Using a Temp Table in a Dynamic Pivot在动态数据透视表中使用临时表
【发布时间】:2014-01-28 18:03:17
【问题描述】:

我正在尝试在动态数据透视查询中使用临时表。我已经读过该过程将不起作用,因为临时表超出了范围,即使它是一个全局表。这对我来说很奇怪,因为它在 sql fiddle 中有效,但在 SQL Server 2012 中无效。如何编辑我的查询,以便它给我一个输出而不是(xxx 行受影响)?

这是我的查询:

SELECT         cc.CaseCaseId AS CaseId, cc.Label AS CaseName, rce.EcoDate,  cc.OperatorName, cc.State, cc.County, ei.IROR,  rce.NDCash
into ##Temp2
FROM            PhdRpt.ReportCaseList_542 AS rcl INNER JOIN
                         CaseCases AS cc ON rcl.CaseCaseId = cc.CaseCaseId INNER JOIN
                         PhdRpt.RptCaseEco_542 AS rce ON rcl.ReportRunCaseId = rce.ReportRunCaseId INNER JOIN
                         PhdRpt.EcoIndicators_542 AS ei ON rcl.ReportRunCaseId = ei.ReportRunCaseId


DECLARE @colsPivot AS NVARCHAR(MAX),
 @colsUnpivot as NVARCHAR(MAX),
 @query AS NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT distinct ',' + QUOTENAME(EcoDate) 
 from ##Temp2
 FOR XML PATH(''), TYPE
 ).value('.', 'NVARCHAR(MAX)') 
 ,1,1,'')

select @colsUnpivot = stuff((select ','+quotename(C.name)
 from sys.columns as C
 where C.object_id = object_id('##Temp2') and
 C.name LIKE 'NDCash%'
 for xml path('')), 1, 1, '')


set @query 
 = 'select *
 from
 (
 select cc.CaseCaseId AS CaseId, cc.Label AS CaseName, rce.EcoDate,  cc.OperatorName, cc.State, cc.County, ei.IROR, val, col
FROM          ##Temp2  
 unpivot
 (
 val
 for col in ('+ @colsunpivot +')
 ) u
 ) x1
 pivot
 (
 max(val)
 for EcoDate in ('+ @colspivot +')
 ) p'

exec(@query)


Drop table ##Temp2

这是表结构:

CaseId       EcoDate          NDCash
2         2003-01-01    26.6384943638238
2         2004-01-01    23.9534867373416
2         2005-01-01    25.9197356158675
2         2006-01-01    25.3280437702064
2         2007-01-01    24.9828609298022
2         2008-01-01    26.4019321789285
2         2009-01-01    26.6384943638238
2         2010-01-01    24.0660715481002
2         2011-01-01    26.6384943638238
2         2012-01-01    22.5718444448345
2         2013-01-01    26.6384943638238

【问题讨论】:

  • 使用 ##global 临时表的一个更直接的问题是,这实际上将并发限制为 1。当两个用户同时运行此代码时,您认为会发生什么?
  • @AaronBertrand 您有什么建议作为解决方案?我是 SQL 新手,因此不胜感激。
  • 我什至没有尝试消化你的问题。我只知道全局##temp 表很少是正确的解决方案。

标签: sql-server pivot unpivot


【解决方案1】:

除非我遗漏了什么,否则您不需要为此使用UNPIVOT,也不需要使用临时表,直接查询数据即可。看起来您当前的查询只是取消透视不需要的一列。您使用 unpivot 将多列转换为多行。

你应该可以使用:

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

select @colsPivot = STUFF((SELECT ',' + QUOTENAME(rce.EcoDate) 
                             from PhdRpt.RptCaseEco_542 AS rce
                             group by rce.EcoDate
                             order by rce.EcoDate
                     FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                     ,1,1,'')

set @query 
 = 'select *
 from
 (
     SELECT cc.CaseCaseId AS CaseId, 
        cc.Label AS CaseName, 
        rce.EcoDate,  
        cc.OperatorName, 
        cc.State, 
        cc.County, 
        ei.IROR,  
        rce.NDCash
    FROM PhdRpt.ReportCaseList_542 AS rcl 
    INNER JOIN CaseCases AS cc 
        ON rcl.CaseCaseId = cc.CaseCaseId 
    INNER JOIN PhdRpt.RptCaseEco_542 AS rce 
        ON rcl.ReportRunCaseId = rce.ReportRunCaseId 
    INNER JOIN PhdRpt.EcoIndicators_542 AS ei 
        ON rcl.ReportRunCaseId = ei.ReportRunCaseId
 ) x1
 pivot
 (
     max(NDCash)
     for EcoDate in ('+ @colspivot +')
 ) p'

exec(@query)

【讨论】:

  • 非常感谢 bluefeet。如果有另一列,比如说“折扣”并且我希望它们都被透视,那么我是否必须使用 unpivot?
  • 是的,当您有多个列要转置时,您需要取消转置。
  • @RolandP(这就是为什么你不“简化”或简化你的问题的原因——人们最终会解决更简单的问题,给你留下问题和更多的问题需要解决。)
  • @AaronBertrand 谢谢你的建议。我试图简化它,以便您可以看到我想要实现的目标。
  • @bluefeet 我在 unpivot 中添加了第二个 C.Name,例如 ' ' 到我的查询中,我收到错误“在列列表中多次指定了“NetGas”列UNPIVOT 运算符。”你知道我为什么会收到这个错误吗?
【解决方案2】:

将 exec(@query) 更改为 sp_executeSQl @query。

exec(@query) 不会在当前上下文中执行,但 sp_executeSQL 将在当前上下文中执行,包括临时表。

【讨论】:

  • 为什么您认为其中一种方法在相同的上下文中有效,而另一种则无效?这里没有问题:CREATE TABLE #x(i INT);INSERT #x SELECT 1;EXEC('SELECT i FROM #x;');EXEC sp_executesql N'SELECT i FROM #x;';DROP TABLE #x;
  • @Surendra Nath GM 我已经更改了它,但它仍然无法执行。
猜你喜欢
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 2019-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多