Сводная таблица и объединенные столбцы - PullRequest
13 голосов
/ 02 октября 2008

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

 ID    TYPE   SUBTYPE    COUNT   MONTH
 1      A      Z          1       7/1/2008
 1      A      Z          3       7/1/2008
 2      B      C          2       7/2/2008
 1      A      Z          3       7/2/2008

Могу ли я использовать SQL для преобразования в это:

ID    A_Z   B_C   MONTH
1     4     0     7/1/2008
2     0     2     7/2/2008
1     0     3     7/2/2008

Таким образом, TYPE, SUBTYPE объединяются в новые столбцы и COUNT суммируется там, где совпадают ID и MONTH.

Любые советы будут оценены. Это возможно в SQL или я должен запрограммировать это вручную?

База данных SQL Server 2005.

Предположим, есть 100 с TYPES и SUBTYPES, поэтому 'A' и 'Z' не должны быть жестко закодированы, а должны генерироваться динамически.

Ответы [ 2 ]

29 голосов
/ 02 октября 2008

SQL Server 2005 предлагает очень полезные операторы PIVOT и UNPIVOT, которые позволяют сделать этот код необслуживаемым с помощью PIVOT и некоторой генерации кода / динамического SQL

/*
CREATE TABLE [dbo].[stackoverflow_159456](
    [ID] [int] NOT NULL,
    [TYPE] [char](1) NOT NULL,
    [SUBTYPE] [char](1) NOT NULL,
    [COUNT] [int] NOT NULL,
    [MONTH] [datetime] NOT NULL
) ON [PRIMARY]
*/

DECLARE @sql AS varchar(max)
DECLARE @pivot_list AS varchar(max) -- Leave NULL for COALESCE technique
DECLARE @select_list AS varchar(max) -- Leave NULL for COALESCE technique

SELECT @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + PIVOT_CODE + ']'
        ,@select_list = COALESCE(@select_list + ', ', '') + 'ISNULL([' + PIVOT_CODE + '], 0) AS [' + PIVOT_CODE + ']'
FROM (
    SELECT DISTINCT [TYPE] + '_' + SUBTYPE AS PIVOT_CODE
    FROM stackoverflow_159456
) AS PIVOT_CODES

SET @sql = '
;WITH p AS (
    SELECT ID, [MONTH], [TYPE] + ''_'' + SUBTYPE AS PIVOT_CODE, SUM([COUNT]) AS [COUNT]
    FROM stackoverflow_159456
    GROUP BY ID, [MONTH], [TYPE] + ''_'' + SUBTYPE
)
SELECT ID, [MONTH], ' + @select_list + '
FROM p
PIVOT (
    SUM([COUNT])
    FOR PIVOT_CODE IN (
        ' + @pivot_list + '
    )
) AS pvt
'

EXEC (@sql)
6 голосов
/ 02 октября 2008
select id,
sum(case when type = 'A' and subtype = 'Z' then [count] else 0 end) as A_Z,
sum(case when type = 'B' and subtype = 'C' then [count] else 0 end) as B_C,
month
from tbl_why_would_u_do_this
group by id, month

Вы меняете требования больше, чем наша маркетинговая команда! Если вы хотите, чтобы он был динамичным, вам нужно отступить от звезд.

...