[更新于2013年12月18日11:22 UTC]
[更新于2013年12月18日14:19 UTC]
[更新于2013年12月19日11:11 UTC]
由于我不知道您使用的表名,所以我创建了一个名为yeahyeah
的表。您应该将其替换为自己表的名称。我插入了您在问题中提到的值(fromdate、todate和duration)。
存储过程应该像这样。我称之为pivotit
。
create procedure pivotit (@start_date date, @end_date date)
as
declare @acols table (i int, d date, l int);
;WITH DateRange AS
(
SELECT @start_date DateValue
UNION ALL
SELECT dateadd(dd,1,DateValue)
FROM DateRange
WHERE dateadd(dd,1,DateValue) <= @end_date
)
insert into @acols (i, d, l)
select id, DateValue, Duration from DateRange
join yeahyeah on ( DateRange.DateValue >= yeahyeah.FromDate
and DateRange.DateValue <= yeahyeah.ToDate);
declare @p varchar(max) = '';
declare @s varchar(max);
select @p = @p + ', [' + CONVERT(varchar,d) + ']' from (select distinct d from @acols) a;
set @p = SUBSTRING(@p,3,len(@p)-2);
set @s = '
declare @start_date date = convert(date,'''+CONVERT(varchar,@start_date,112)+''',112);
declare @end_date date = convert(date,'''+CONVERT(varchar,@end_date,112)+''',112);
declare @acols table (i int, d date, l int);
;WITH DateRange AS
(
SELECT @start_date DateValue
UNION ALL
SELECT dateadd(dd,1,DateValue)
FROM DateRange
WHERE dateadd(dd,1,DateValue) <= @end_date
)
insert into @acols (i, d, l)
select id, DateValue, Duration from DateRange
join yeahyeah on ( DateRange.DateValue >= yeahyeah.FromDate
and DateRange.DateValue <= yeahyeah.ToDate);
with cart as
(
select distinct
a.i
, b.d
from @acols a
join @acols b
on 1=1
)
insert into @acols (i, d, l)
select cart.i
, cart.d
, 0
from cart
left outer join
@acols a
on cart.i = a.i
and cart.d = a.d
where a.i is null;
select id, '+@p+'
from
( select convert(varchar,d) as d
, l
, i as id
from @acols ) as sourcetable
pivot (
sum(l)
for d in ('+@p+')
) as pivottable';
execute(@s);
创建过程后,您可以执行以下操作:
exec pivotit @start_date = '2013-01-01', @end_date = '2013-01-31'
然后会产生以下结果: