Сводные данные в T-SQL - PullRequest
       28

Сводные данные в T-SQL

5 голосов
/ 29 августа 2011

У меня есть группа людей. Позволяет называть их A, B, C. У меня есть таблица, которая показывает, сколько им платили каждый месяц ....

PERSON|MONTH|PAID
A      JAN   10
A      FEB   20   
B      JAN   10   
B      FEB   20   
B      SEP   30   
C      JAN   10   
C      JUNE  20   
C      JULY  30   
C      SEP   40 

ЭТА таблица может продолжаться годами.

Есть ли способ сводить эту таблицу (как мне кажется, на самом деле ничего не нужно агрегировать, что обычно делается в сводках) В таблице, которая выглядит следующим образом?

     JAN    FEB    MAR    APR    MAY    JUN    JUL    AGU    SEP
A    10     20
B    10     20     -      -      -      -      -      -      30
C    10     -      -      -      -      20     30     -      40

Раньше не сталкивался с чем-то подобным, но предположил, что это общая проблема, идеи?

Ответы [ 2 ]

3 голосов
/ 29 августа 2011

Если вы используете SQL Server 2005 (или выше), вот код:

DECLARE @cols VARCHAR(1000)
DECLARE @sqlquery VARCHAR(2000)

SELECT  @cols = STUFF(( SELECT distinct  ',' + QuoteName([Month])
                        FROM YourTable FOR XML PATH('') ), 1, 1, '') 


SET @sqlquery = 'SELECT * FROM
      (SELECT Person, Month, Paid
       FROM YourTable ) base
       PIVOT (Sum(Paid) FOR [Person]
       IN (' + @cols + ')) AS finalpivot'

EXECUTE ( @sqlquery )

Это будет работать независимо от того, сколько у вас различных статусов.Он динамически собирает запрос с PIVOT.Единственный способ сделать PIVOT с динамическими столбцами - это динамически собрать запрос, что можно сделать в SQL Server.

Другие примеры:

2 голосов
/ 29 августа 2011

Я не уверен, зачем вам динамическое число столбцов, поскольку в году всегда 12 месяцев.Кроме того, названия ваших месяцев кажутся немного непоследовательными по длине.

Пример набора результатов:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID]
UNION SELECT 'A','FEB',20
UNION SELECT 'B','JAN',10
UNION SELECT 'B','FEB',20
UNION SELECT 'B','SEP',30
UNION SELECT 'C','JAN',10
UNION SELECT 'C','JUNE',20
UNION SELECT 'C','JULY',30
UNION SELECT 'C','SEP',40) AS A
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p

Для вашей таблицы это будет:

SELECT [PERSON],[MONTH],[PAID]
FROM [YOURTABLE]
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p

Если вы добавитестолбец год выглядит так:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID], 2011 [YEAR]
UNION SELECT 'A','FEB',20, 2011
UNION SELECT 'B','JAN',10, 2011
UNION SELECT 'A','FEB',20, 2010
UNION SELECT 'B','JAN',10, 2010
UNION SELECT 'B','FEB',20,2011
UNION SELECT 'B','SEP',30,2011
UNION SELECT 'C','JAN',10,2011
UNION SELECT 'C','JUNE',20,2011
UNION SELECT 'C','JULY',30,2011
UNION SELECT 'C','SEP',40,2011) AS A
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p
...