【问题标题】:Pivoting with Sum function in tsql使用 sql 中的 Sum 函数进行透视
【发布时间】:2012-07-05 16:23:42
【问题描述】:

我有以下格式的数据

Client       Business Unit    Year  Quarter     USD Amt
BalckRock    Pricing          2010  Q1          234
BalckRock    Pricing          2010  Q2          343
BalckRock    Pricing          2010  Q3          545
BalckRock    Pricing          2010  Q4          5435
BalckRock    Pricing          2011  Q1          5425
BalckRock    Pricing          2011  Q2          3524
BalckRock    Pricing          2011  Q3          54
BalckRock    Pricing          2011  Q4          5425
BalckRock    Pricing          2012  Q1          545
BalckRock    Pricing          2012  Q2          5445
BalckRock    Pricing          2012  Q3          545
BalckRock    Pricing          2012  Q4          4545
BalckRock    Sales            2010  Q1          23
BalckRock    Sales            2010  Q2          3434
BalckRock    Sales            2010  Q3          4234
BalckRock    Sales            2010  Q4          4234
BalckRock    Sales            2011  Q1          3423
BalckRock    Sales            2011  Q2          1
BalckRock    Sales            2011  Q3          1341
BalckRock    Sales            2011  Q4          434
BalckRock    Sales            2012  Q1          421
BalckRock    Sales            2012  Q2          42
BalckRock    Sales            2012  Q3          434
BalckRock    Sales            2012  Q4          4214

我希望它采用以下格式

Client        Business Unit    2010    2011    2012
BalckRock     Pricing          6557    14428   11080
BalckRock     Sales            11925   5199    5111

基本上是每年美元的总和,但列标题是年份

谁能帮我解决这个问题?

【问题讨论】:

标签: tsql pivot-table


【解决方案1】:

有不同的方式,你可以使用PIVOT(静态或动态,取决于你的需要)或者你可以简单地使用CASE

SELECT  Client,
        [Business Unit],
        SUM(CASE WHEN [Year] = 2010 THEN [USD Amt] ELSE 0 END) [2010],
        SUM(CASE WHEN [Year] = 2011 THEN [USD Amt] ELSE 0 END) [2011],
        SUM(CASE WHEN [Year] = 2012 THEN [USD Amt] ELSE 0 END) [2012]
FROM YourTable
GROUP BY Client, [Business Unit]

使用PIVOT

SELECT *
FROM (  SELECT Client, [Business Unit], [USD Amt], [Year]
        FROM YourTable) T
PIVOT (SUM([USD Amt]) FOR [Year] IN ([2010],[2011],[2012])) PT

【讨论】:

  • 值得注意的是,在 FROM 子句中有一个子选择的原因是因为 PIVOT 会自动按 PIVOT 本身未使用的列进行分组。因此,在此示例中,[USD Amt] 和 [Year] 在 PIVOT 中,因此所有内容都将按 [Client] + [Business Unit] 分组
【解决方案2】:

您可以轻松地为此使用PIVOT。正如其他人所说,您可以使用对所需列进行编码的静态枢轴,也可以使用动态枢轴,在运行时获取列列表。

静态枢轴(参见Sql Fiddle for Demo

select *
from
(
  select client, businessunit, year, USD_Amount
  from t
) x
pivot
(
  sum(USD_Amount)
  for year in ([2010], [2011], [2012])
) p

但是为此,我可能会推荐一个动态 Pivot,这样您就不必在进入新的一年时更改代码。 (见Sql Fiddle with Demo

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


select @cols = STUFF((SELECT distinct ',' + QUOTENAME(year) 
                    from t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT client, businessunit, ' + @cols + ' from 
             (
                select client, businessunit, year, USD_Amount
                from t
            ) x
            pivot 
            (
                sum(USD_Amount)
                for year in (' + @cols + ')
            ) p '

execute(@query)

两个查询将产生相同的结果。但是,动态数据透视的好处是,当您有来自其他年份的数据时,您不必更新查询以包含这些字段。查询的第一部分获取表中distinct years 的列表,然后使用years 的列表来确定您要查找的SUM

【讨论】:

  • 如果您使用与当前年份的差异而不是当前年份,则不需要动态数据透视表:(year(getdate()) - year) 作为 difYear 并在 for:FOR [difYear] IN ( [2], [1], [0], select 可以是:[2] AS 'Previous Year-1', [1] AS 'Previous Year', [0] AS 'Current Year'跨度>
【解决方案3】:

-- 一行五列的数据透视表

SELECT Client  Business Unit   Year    Quarter USD Amt,[2010],[2011],[2012]
FROM
(SELECTClient  Business Unit   Year    Quarter USD Amt 
    FROM Table) AS SourceTable
PIVOT
(
sum(USD Amt)
FOR Year IN ([2010], [2011], [2012])
) AS PivotTable;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 2011-09-18
    • 2018-09-07
    • 2020-01-31
    相关资源
    最近更新 更多