为了将expense 和revenue 列都作为date 的标题,我建议同时应用UNPIVOT 和PIVOT 函数。
UNPIVOT 会将费用和收入列转换为您可以附加日期的行。将日期添加到列名后,您就可以应用 PIVOT 函数了。
UNPIVOT 代码将是:
select id,
col+'_'+convert(varchar(10), date, 110) new_col,
value
from yt
unpivot
(
value
for col in (expense, revenue)
) un
见SQL Fiddle with Demo。这会产生一个结果:
| ID | NEW_COL | VALUE |
-----------------------------------
| 1 | expense_12-31-2012 | 43 |
| 1 | revenue_12-31-2012 | 45 |
| 2 | expense_01-01-2013 | 32 |
如您所见,费用/收入列现在是带有 new_col 的行,该行是通过将日期连接到末尾而创建的。然后在 PIVOT 中使用此 new_col:
select id,
[expense_12-31-2012], [revenue_12-31-2012],
[expense_01-01-2013], [revenue_01-01-2013],
[expense_01-31-2013], [revenue_01-31-2013],
[expense_03-03-2013], [revenue_03-03-2013]
from
(
select id,
col+'_'+convert(varchar(10), date, 110) new_col,
value
from yt
unpivot
(
value
for col in (expense, revenue)
) un
) src
pivot
(
sum(value)
for new_col in ([expense_12-31-2012], [revenue_12-31-2012],
[expense_01-01-2013], [revenue_01-01-2013],
[expense_01-31-2013], [revenue_01-31-2013],
[expense_03-03-2013], [revenue_03-03-2013])
) piv;
见SQL Fiddle with Demo。
如果您将已知数量的日期转换为列,上述版本将非常有用,但如果您有未知数量的日期,那么您将需要使用动态 SQL 来生成结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(c.col+'_'+convert(varchar(10), yt.date, 110))
from yt
cross apply
(
select 'expense' col union all
select 'revenue'
) c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id,' + @cols + '
from
(
select id,
col+''_''+convert(varchar(10), date, 110) new_col,
value
from yt
unpivot
(
value
for col in (expense, revenue)
) un
) src
pivot
(
sum(value)
for new_col in (' + @cols + ')
) p '
execute(@query);
见SQL Fiddle with Demo。两个查询生成相同的结果。