Поворот с функцией Sum в tsql

У меня есть данные в следующем формате

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

В основном это сумма в долларах США по годам, но количество лет в заголовке столбца

Кто-нибудь может мне в этом помочь?


person Abhinav Awasthi    schedule 05.07.2012    source источник
comment
Опубликуйте свой существующий код sql, что вы пробовали?   -  person rs.    schedule 05.07.2012
comment
проверьте код из этого вопроса - stackoverflow.com/questions/1122117/   -  person rs.    schedule 05.07.2012


Ответы (3)


Есть разные способы, вы можете использовать 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
person Lamak    schedule 05.07.2012
comment
Стоит отметить, что причина, по которой в предложении FROM есть подвыбор, заключается в том, что PIVOT автоматически группирует столбцы, которые не используются в самом PIVOT. Итак, в этом примере [USD Amt] и [Year] находятся в PIVOT, поэтому все будет сгруппировано по [Client] + [Business Unit] - person Sal; 16.07.2019

Для этого вы можете легко использовать PIVOT. Как сказал другой, вы можете использовать Static Pivot, в котором вы кодируете нужные столбцы, или вы можете использовать Dynamic Pivot, который получает список столбцов во время выполнения.

Статическая сводка (см. Sql Fiddle для демонстрации)

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 с демонстрацией)

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, который вы ищете.

person Taryn    schedule 06.07.2012
comment
Вам не нужен динамический сводный график, если вы используете вместо текущего года разницу с текущим годом: (year (getdate ()) - year) как difYear и в for: FOR [difYear] IN ([2], [1 ], [0], выбор может быть таким: [2] КАК «Предыдущий год-1», [1] КАК «Предыдущий год», [0] КАК «Текущий год» - person EckhardN; 02.06.2020

- Сводная таблица с одной строкой и пятью столбцами

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;
person abianari    schedule 05.07.2012