在处理此动态 SQL 版本之前,我将首先使用您的有限日期将查询编写为静态版本。为了得到结果,我会计算你在子查询中需要的值,然后在weekenddates
.
如果您的值数量有限,基本语法是:
select name, startdate, enddate,
value, factor,
coalesce([2013-08-18], 0) [2013-08-18],
coalesce([2013-08-25], 0) [2013-08-25],
coalesce([2013-09-01], 0) [2013-09-01],
coalesce([2013-09-08], 0) [2013-09-08]
from
(
select a.name,
a.startdate,
a.enddate,
a.value,
a.factor,
convert(varchar(10), r.weekenddate, 120) weekenddate,
amt = a.value * a.factor
from assignments a
inner join reportingweeks r
on r.weekenddate >= a.startdate
and r.weekenddate <= a.enddate
) d
pivot
(
sum(amt)
for weekenddate in ([2013-08-18], [2013-08-25], [2013-09-01],
[2013-09-08])
) piv;
请参阅SQL Fiddle with Demo。一旦有了正确的逻辑,就可以将查询转换为动态 SQL:
DECLARE @cols AS NVARCHAR(MAX),
@colsNull AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(dt)
from
(
select convert(varchar(10), weekenddate, 120) dt
from reportingweeks
) d
group by dt
order by dt
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsNull = STUFF((SELECT ', coalesce(' + QUOTENAME(dt)+', 0) as '+QUOTENAME(dt)
from
(
select convert(varchar(10), weekenddate, 120) dt
from reportingweeks
) d
group by dt
order by dt
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT name, startdate, enddate,
value, factor, ' + @colsNull + '
from
(
select a.name,
a.startdate,
a.enddate,
a.value,
a.factor,
convert(varchar(10), r.weekenddate, 120) weekenddate,
amt = a.value * a.factor
from assignments a
inner join reportingweeks r
on r.weekenddate >= a.startdate
and r.weekenddate <= a.enddate
) x
pivot
(
sum(amt)
for weekenddate in (' + @cols + ')
) p '
execute sp_executesql @query;
请参阅SQL Fiddle with Demo。两者都会给出结果:
| NAME | STARTDATE | ENDDATE | VALUE | FACTOR | 2013-08-18 | 2013-08-25 | 2013-09-01 | 2013-09-08 |
|-------|------------|------------|-------|--------|------------|------------|------------|------------|
| Alice | 2013-08-29 | 2014-03-22 | 200 | 0.8 | 0 | 0 | 160 | 160 |
| Bob | 2013-07-27 | 2013-11-01 | 140 | 1 | 140 | 140 | 140 | 140 |
| Jim | 2013-08-01 | 2013-09-06 | 200 | 0.5 | 100 | 100 | 100 | 0 |
| Jim | 2013-08-20 | 2013-09-01 | 250 | 0.5 | 0 | 125 | 125 | 0 |