Tableau croisé dynamique et concaténer des colonnes
-
03-07-2019 - |
Question
J'ai une base de données au format suivant:
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
Puis-je utiliser SQL pour le convertir en ceci:
ID A_Z B_C MONTH
1 4 0 7/1/2008
2 0 2 7/2/2008
1 0 3 7/2/2008
Ainsi, les TYPE
, SUBTYPE
sont concaténés dans de nouvelles colonnes et COUNT
est additionné, où ID
et correspondance mois
.
Tous les conseils seraient appréciés. Est-ce possible en SQL ou devrais-je le programmer manuellement?
La base de données est SQL Server 2005.
Supposons qu'il existe une centaine de TYPES
et de SUBTYPES
, de sorte que "A" et "Z" ne doivent pas être codés en dur mais générés de manière dynamique.
La solution
SQL Server 2005 est un opérateur très utile pour PIVOT et UNPIVOT qui vous permet d’économiser ce code sans maintenance à l’aide de PIVOT et de la génération de code / SQL dynamique
/*
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)
Autres conseils
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
Vous modifiez davantage les exigences que notre équipe marketing! Si vous voulez qu'il soit dynamique, vous devrez vous rabattre sur un sproc.