将自定义列添加到数据透视表

问题描述 投票:0回答:1

给定两个这样的表:

表1

Counterparty  Product  Deal  Date          Value
foo           bar      Buy    01/01/24     10.00
foo           bar      Buy    01/01/24     10.00
foo           bar      Sell   01/01/24     10.00
foo           bar      Sell   01/01/24     10.00
fizz          bar      Buy    01/01/24     10.00
fizz          bar      Buy    01/01/24     10.00
fizz          buzz     Sell   01/01/24     10.00
fizz          buzz     Sell   01/01/24     10.00

表2

Counterparty  Product  Deal  Date          Value
foo           bar      Buy    01/01/24     11.00
foo           bar      Buy    01/01/24     09.00
foo           bar      Sell   01/01/24     09.00
foo           bar      Sell   01/01/24     10.00
fizz          bar      Buy    01/01/24     12.00
fizz          bar      Buy    01/01/24     08.00
fizz          buzz     Sell   01/01/24     09.00
fizz          buzz     Sell   01/01/24     10.00

我需要产生这样的输出:


Counterparty  Bar  Buzz  Total  col1 col2 col3 col4
foo           40    0      40    39    1   0    40 
fizz          20    20     40    39    1   0    40
Total         60    20     80    78    2   0    40

哪里

  • col1
    Total
    相同,但源自
    table2
  • col2
    Total
    col1
  • 之间的区别
  • col3
    应填写 0```
  • col4
    Total
    col3
  • 之间的区别

到目前为止,我可以创建动态 SQL 查询,但我不知道如何添加额外的列并执行必要的操作:

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

-- Get Distinct Commodities
WITH cte AS (
    SELECT DISTINCT Commodity
    FROM Sample 
)
-- Generate dynamic columns from the table
SELECT @cols = COALESCE(@cols + ', ', '') + 'ISNULL(' + QUOTENAME(Commodity) + ', 0) AS ' + QUOTENAME(Commodity),
       @colsPivot = COALESCE(@colsPivot + ', ', '') + QUOTENAME(Commodity)
FROM cte
ORDER BY Commodity

-- add static columns to the pivot list:
SET @colsPivot = @colsPivot + ', [col1], [col2], [col3], [col4]'

-- Build the final query
SET @query = 
   'SELECT Counterparty, ' + @cols + ' 
    FROM (
        SELECT Counterparty, Commodity, SUM([Value]) AS TotalExposure
        FROM Sample
        GROUP BY Counterparty, Commodity
    ) AS pivotData
    PIVOT (
        SUM(TotalExposure)
        FOR Commodity IN (' + @colsPivot + ') --here lies the issue
    ) AS pivotTable'

PRINT(@query);

输出:

Counterparty   Bar      Buzz
Fizz           20.00    20.00
Foo            40.00    0.00

我假设我需要将 CTE 表达式中的额外列值与将额外列与每个交易对手相匹配的表连接起来,但我很难将其可视化并创建查询。

sql sql-server
1个回答
0
投票

我会采取不同的方法。首先

UNION ALL
添加源 = 1 或 2 列后的两个源。接下来,对
Counterparty
上的组合数据进行分组,并使用 条件聚合 有选择地对剩余每个结果列的值进行求和。

要添加总计行,您可以将

WITH ROLLUP
选项添加到
GROUP BY
并添加一些逻辑以有条件地将
Counterparty
列设置为
'Total'

SELECT
    CASE WHEN GROUPING(Counterparty) = 0 THEN Counterparty ELSE 'Total' END AS Counterparty,
    SUM(CASE WHEN Src = 1 AND Product = 'bar' THEN Value END) AS Bar,
    SUM(CASE WHEN Src = 1 AND Product = 'buzz' THEN Value END) AS Buzz,
    SUM(CASE WHEN Src = 1 THEN Value END) AS Total,
    SUM(CASE WHEN Src = 2 THEN Value END) AS Col1,
    SUM(CASE WHEN Src = 1 THEN Value END) - SUM(CASE WHEN Src = 2 THEN Value END) AS Col2,
    0 AS Col3,
    SUM(CASE WHEN Src = 1 THEN Value END) - 0 AS Col4
FROM (
    SELECT *, Src = 1 FROM Table1
    UNION ALL
    SELECT *, Src = 2 FROM Table2
) U
GROUP BY Counterparty WITH ROLLUP
ORDER BY GROUPING(Counterparty), Counterparty

结果:

交易对手 酒吧 嗡嗡声 总计 第 1 栏 第 2 栏 第 3 栏 第 4 栏
嘶嘶声 20.00 20.00 40.00 39.00 1.00 0 40.00
40.00 40.00 39.00 1.00 0 40.00
总计 60.00 20.00 80.00 78.00 2.00 0 80.00

如果您的产品可能不仅仅包含“bar”和“buzz”,您可以使用 dynamic SQL 来生成这些列。

请参阅 这个 SQL Fiddle 进行演示。

© www.soinside.com 2019 - 2024. All rights reserved.