您可以使用该PIVOT
函数来获取结果。
我建议这样做的方法是先编写一个硬编码版本,然后将其转换为动态 sql。
Actual Cost
注意:我通过除以项目开始/项目结束之间的天数来确定每月的成本。这至少应该让您开始编写实际报告。
静态版本将与此类似:
;with cte as
(
select projectname, [ACTUAL COST], [PROJECTSTART], [PROJECTEND]
from yourtable
union all
select projectname, [ACTUAL COST],
dateadd(d, 1, PROJECTSTART),
PROJECTEND
from cte
where dateadd(d, 1, PROJECTSTART) <= ProjectEnd
)
select *
from
(
select
my.projectname,
my.monthyear,
my.totaldayspermonth * a.perdaycost AmountPerMonth
from
(
select projectname,
left(datename(m, projectstart), 3) + cast(year(projectstart) as varchar(4)) monthyear,
count(*) TotalDaysPerMonth
from cte
group by projectname,
[actual cost],
left(datename(m, projectstart), 3) + cast(year(projectstart) as varchar(4))
) my
cross apply
(
select projectname,
round([actual cost] / (datediff(d, projectstart, projectend) *1.0), 2) PerDayCost
from yourtable a
where my.projectname = a.projectname
) a
) src
pivot
(
max(AMOUNTPERMONTH)
for monthyear in (Dec2011, Jan2012, Feb2012, Mar2012,
Apr2012, May2012, Jun2012, Jul2012, Aug2012)
) piv
OPTION(MAXRECURSION 0);
请参阅SQL Fiddle with Demo。
一旦有了静态版本,就可以更轻松地将其转换为动态 SQL。动态 SQL 将是:
;with cte as
(
select projectname, [ACTUAL COST], [PROJECTSTART], [PROJECTEND]
from yourtable
union all
select projectname, [ACTUAL COST],
dateadd(d, 1, PROJECTSTART),
PROJECTEND
from cte
where dateadd(d, 1, PROJECTSTART) <= ProjectEnd
)
select *
into #dates
from cte
OPTION(MAXRECURSION 0)
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(left(datename(m, projectstart), 3) + cast(year(projectstart) as varchar(4)))
from #dates
group by datename(m, projectstart), year(projectstart), month(projectstart)
order by year(projectstart), month(projectstart)
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = ';with cte as
(
select projectname, [ACTUAL COST], [PROJECTSTART], [PROJECTEND]
from yourtable
union all
select projectname, [ACTUAL COST],
dateadd(d, 1, PROJECTSTART),
PROJECTEND
from cte
where dateadd(d, 1, PROJECTSTART) <= ProjectEnd
)
select projectname, '+@cols+'
from
(
select
my.projectname,
my.monthyear,
my.totaldayspermonth * a.perdaycost AmountPerMonth
from
(
select projectname,
left(datename(m, projectstart), 3) + cast(year(projectstart) as varchar(4)) monthyear,
count(*) TotalDaysPerMonth
from cte
group by projectname,
[actual cost],
left(datename(m, projectstart), 3) + cast(year(projectstart) as varchar(4))
) my
cross apply
(
select projectname,
round([actual cost] / (datediff(d, projectstart, projectend) *1.0), 2) PerDayCost
from yourtable a
where my.projectname = a.projectname
) a
) src
pivot
(
max(AMOUNTPERMONTH)
for monthyear in ('+@cols+')
)piv
OPTION(MAXRECURSION 0)'
execute(@query)
请参阅带有演示的 SQL Fiddle
两个查询的结果是:
| PROJECTNAME | DEC2011 | JAN2012 | FEB2012 | MAR2012 | APR2012 | MAY2012 | JUN2012 | JUL2012 |
-----------------------------------------------------------------------------------------------
| abc | 191.27 | 191.27 | 178.93 | 191.27 | 185.1 | 191.27 | 185.1 | 191.27 |
| prj1 | (null) | 155.48 | 196.04 | 209.56 | 202.8 | 209.56 | 202.8 | (null) |
| xyz | (null) | 178.34 | 2585.93 | 2675.1 | (null) | (null) | (null) | (null) |