问题
I'm trying to implement a dynamic pivoting in SQL to represent my results given below
ID Charge Message Amt Of Billing
4563 WEB FEE 9.75
4563 MONTHLY FEE 6
4563 CLUB FEE 9.95
4648 MONTHLY FEE 6
4648 ACCOUNT FEE 5
4648 CLUB FEE 9.95
4648 WEB FEE 9.75
4650 MONTHLY FEE 6
4650 WEB FEE 9.75
4650 CLUB FEE 9.95
into a desired representation like this.
ID ACCOUNT FEE MONTHLY FEE CLUB FEE WEB FEE
4563 6 9.95 9.75
4648 5 6 9.95 9.75
4650 6 9.95 9.75
Your help is highly appreciated.
回答1:
For a dynamic pivot, you could use something like this:
declare @cols nvarchar(max);
declare @sql nvarchar(max);
select @cols = stuff((
select distinct
', ' + quotename(isnull(nullif(ChargeMessage,''),'unknown'))
from t
order by 1
for xml path (''), type).value('.','nvarchar(max)')
,1,1,'')
select @sql ='
select Id, ' + @cols +'
from (
select Id, ChargeMessage= isnull(nullif(ChargeMessage,''''),''unknown''), AmtOfBilling
from t
) as t
pivot (sum([AmtOfBilling]) for [ChargeMessage] in (' + @cols +')) p'
select @sql
exec(@sql);
rextester demo: http://rextester.com/NRRGA52425
returns: (included an empty string for test data)
+------+-------------+----------+-------------+---------+---------+
| Id | ACCOUNT FEE | CLUB FEE | MONTHLY FEE | unknown | WEB FEE |
+------+-------------+----------+-------------+---------+---------+
| 4563 | NULL | 9,95 | 6,00 | NULL | 9,75 |
| 4648 | 5,00 | 9,95 | 6,00 | NULL | 9,75 |
| 4650 | NULL | 9,95 | 6,00 | 9,95 | 9,75 |
+------+-------------+----------+-------------+---------+---------+
Query that is generated:
select Id, [ACCOUNT FEE], [CLUB FEE], [MONTHLY FEE], [unknown], [WEB FEE]
from (
select Id, ChargeMessage= isnull(nullif(ChargeMessage,''),'unknown'), AmtOfBilling
from t
) as t
pivot (sum([AmtOfBilling]) for [ChargeMessage]
in ( [ACCOUNT FEE], [CLUB FEE], [MONTHLY FEE], [unknown], [WEB FEE])) p
dynamic conditional aggregation:
declare @cols nvarchar(max);
declare @sql nvarchar(max);
select @cols = stuff((
select distinct
char(10)+' , '
+ quotename(isnull(nullif(ChargeMessage,''),'unknown'))
+' = sum(case when ChargeMessage = '''+ChargeMessage+''' then AmtOfBilling end)'
from t
order by 1
for xml path (''), type).value('.','nvarchar(max)')
,1,0,'')
select @sql ='
select Id'+@cols+'
from t
group by Id'
select @sql
exec(@sql);
Query Generated:
select Id
, [ACCOUNT FEE] = sum(case when ChargeMessage = 'ACCOUNT FEE' then AmtOfBilling end)
, [CLUB FEE] = sum(case when ChargeMessage = 'CLUB FEE' then AmtOfBilling end)
, [MONTHLY FEE] = sum(case when ChargeMessage = 'MONTHLY FEE' then AmtOfBilling end)
, [unknown] = sum(case when ChargeMessage = '' then AmtOfBilling end)
, [WEB FEE] = sum(case when ChargeMessage = 'WEB FEE' then AmtOfBilling end)
from t
group by Id
来源:https://stackoverflow.com/questions/42657365/dynamic-pivot-issue-in-sql-server-2012