【问题标题】:Perform Operations on Dynamic Columns from Pivot从 Pivot 对动态列执行操作
【发布时间】:2018-01-03 13:58:14
【问题描述】:

正如问题所说,我正在尝试使用 Pivot 将一些值从动态 sql 查询插入到 TempTable,所以我不知道 ExistingCoulmnName

在下一步中,我想执行一些算术运算,比如说对这些列值进行乘法运算。

我该怎么做?

附上一些样本:

select @cols = STUFF((SELECT ',' + QUOTENAME(FYYear) 
                from #TempCapEx
                group by FYYear
                order by FYYear
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

set @query = 'SELECT CapitalExpenditureId,' + @cols + ' into  
         ##GlobalTempForCapExPivotResult from 
         (
            select CapitalExpenditureId, FYYear, indicatorvalue
            from #TempCapEx
        ) x
        pivot 
        (
            sum(indicatorvalue)
            for FYYear in (' + @cols + ')
        ) p'

execute (@query ) ;

所以我有一个##GlobalTempForCapExPivotResult

CapitalExpenditureId    2016-2017   2017-2018   2018-2019   2019-2020   2020-2021   2021-2022   2022-2023
22150                   0.0000      35200.0000  35200.0000  35200.0000  35200.0000  35200.0000  NULL
32632                   NULL        213695.0000 224379.0000 235599.0000 247379.0000 259748.0000 0.0000
1589                    10252.0000  170370.0000 0.0000      0.0000      0.0000      0.0000      NULL
14988                   0.0000      133000.0000 0.0000      0.0000      0.0000      0.0000      NULL
36877                   NULL        303.0300    404.040     101.010     0.0000      0.0000      0.0000

所以财政年度列可能会增加或减少,所以我该怎么做这样的事情:

Select [ExistingCoulmnName] * 3.5 from #GlobalTempForCapExPivotResult where [ExistingCoulmnName] = '[2016-2017]'

预期输出:

CapitalExpenditureId    2016-2017   2017-2018        2018-2019          2019-2020         2020-2021        2021-2022        2022-2023
22150                   0.00 * 3.5  35200.0000 * 3.5 35200.0000 * 3.5  35200.0000 * 3.5  35200.0000 * 3.5 35200.0000 * 3.5  NULL * 3.5

【问题讨论】:

  • 您只想要那一列,还是现有列,再加上一列新列?您希望将该列添加到临时表中,还是在创建临时表后作为单独的查询?我还假设您正在传递一个值为'2016-2017' 的参数/变量? (显示您想要的确切输出。)
  • @MatBailie 你只是想要那一列,还是现有列,再加上一列新列? Existing Columns 您希望将该列添加到临时表中,还是在创建临时表后作为单独的查询? Separate Query 我还假设您正在传递一个值为“2016-2017”的参数/变量? Yes
  • 请不要只在 cmets 中回复,更新您的问题以向所有读者阐明场景。 (不是每个人都会读完所有的cmets。) 请同时给出一个完整的例子;您已经给出了示例输入数据,请给出示例预期结果。

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


【解决方案1】:

在标准 SQL 语句中没有本地方法可以做到这一点。相反,您使用某种语言(甚至可能是 T-SQL) 将新查询写入字符串,然后执行该新查询。与您的示例几乎相同。

DECLARE @field NVARCHAR(256) = N'2015-2016';

DECLARE @dynamicSelect NVARCHAR(MAX);

SET @dynamicSelect = N'SELECT *, 3.5 * [' + @field + N'] AS new_field FROM ##GlobalTempForCapExPivotResult';

EXECUTE(@dynamicSelect);

另外,请注意,此类问题是为什么您不应该首先创建该全局临时表。规范化的数据结构对 SQL 更友好。在 SQL 的外部进行格式化。

这是您没有全局临时表的查询...

SELECT
  CapitalExpenditureId,
  FYYear,
  indicatorvalue * 3.5
FROM
  #TempCapEx
GROUP BY
  CapitalExpenditureId,
  FYYear
ORDER BY
  CapitalExpenditureId,
  FYYear

作为人类可能更喜欢平面文件(excel样式)表格,但这样做是一个非常糟糕的主意在 SQL 中使用的表类型。坚持规范化的数据结构,并学习如何使用它们。不要试图破坏 SQL。

【讨论】:

  • 如果我想对所有列和所有行都暗示这一点怎么办?
  • 您完全按照您在示例查询中所做的操作来首先创建全局临时表。您遍历所有要包含的字段,并将它们构建到您的新 @dynamicSelect 并执行它...
  • 查询中的第4个dynamicSql会​​不会影响性能?
  • COALESCE(<some-field>, <default-value>) 将用<default-value> 替换所有出现的NULL <some-field>
  • 我建议提出一个新问题。但是,不要问“我该如何实现这个解决方案”,而是问“我该如何解决这个问题”?给出示例起始数据、您需要实施的规则和示例预期结果。这个问题可以解释为“已经达到了这个有问题的位置,我该如何继续”,最好的答案应该是“不要,你应该回去并以不同的方式做第一步”。
【解决方案2】:

你需要创建一个动态的 UPDATE 语句:

DECLARE
    @UPDATEList NVARCHAR(MAX) = N''
    , @DynamicSQL NVARCHAR(MAX) = N'UPDATE ##GlobalTempForCapExPivotResult
SET ';

SELECT @UPDATEList += N'
    , '
    + QUOTENAME(FYYear) + N' = ' + QUOTENAME(FYYear) + N' * 3.5'
FROM #TempCapEx
GROUP BY FYYear;

SELECT @UPDATEList = SUBSTRING(@UPDATEList, 6, LEN(@UPDATEList) - 5);
SELECT @DynamicSQL += @UPDATEList + ';';

EXEC (@DynamicSQL);

更新全局临时表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 2018-11-28
    • 1970-01-01
    • 2020-09-11
    • 2020-09-22
    • 1970-01-01
    相关资源
    最近更新 更多