Here a solution which generates a calendar using recursion
then adding columns and updating them using cursor and dynamic script
set dateformat dmy
declare @table as table(pk int, startdate date,enddate date,rent int,cost float)
insert into @table values(3435,'01/04/2018','12/02/2020',500,11210.95),(5456,'14/06/2019','01/02/2020',700,5339.18)
declare @table2 as table(pk int)
insert into @table2 select distinct(pk) from @table
declare @calendar as table (date date)
declare @mindate as date
declare @maxdate as date
select @mindate=min(startdate) from @table
select @maxdate=max(enddate) from @table;
with cte as(select @mindate as mydate union all select dateadd(day,1,mydate) from cte
where mydate < @maxdate)
insert into @calendar select * from cte
option(maxrecursion 0);
declare @tabresultsrows as table(pk int,MO varchar(7),N int,M int,Y int);
declare @tabmonths as table(Mo varchar(7),M int,Y int);
with cal as(
select t2.pk,c.date ,t.startdate,t.enddate ,month(date) M, year(date) y ,concat(RIGHT('00' + CONVERT(NVARCHAR(2), month(date)), 2),'/', year(date)) Mo,
case when c.date >= t.startdate and c.date <=t.enddate then 1 else 0 end N from @calendar c
cross join @table2 t2
inner join @table t on t2.pk=t.pk),
caltab as(select pk,Mo,sum(N) N ,Y,M from cal group by pk,Y,M,Mo )
insert into @tabresultsrows select pk,MO,N,M,Y from caltab order by pk,Y,M
insert into @tabmonths select distinct(MO),M,Y from @tabresultsrows
IF OBJECT_ID('tempdb..#tabresultscolumns') IS NOT NULL DROP TABLE #tabresultscolumns
select * into #tabresultscolumns from @table
declare @script as varchar(max)
declare mycursor cursor for select mo from @tabmonths order by Y,M
declare @mo as varchar(7)
open mycursor
fetch mycursor into @mo
while @@fetch_status=0
begin
set @script='alter table #tabresultscolumns add ['+@mo+'] int'
print @script
exec(@script)
fetch mycursor into @mo
end
close mycursor
deallocate mycursor
declare secondcursor cursor for select pk,Mo,N from @tabresultsrows
declare @PK AS INT
declare @n as int
open secondcursor
fetch secondcursor into @pk,@mo,@n
while @@fetch_status=0
begin
set @script=concat('update #tabresultscolumns set ['+@mo+']=',@n,' where pk=',@pk )
print @script
exec(@script)
fetch secondcursor into @pk,@mo,@n
end
close secondcursor
deallocate secondcursor
select * from #tabresultscolumns