February 20, 2024 at 6:56 pm
IMHO, Steve Collins' post (with a tiny tweak (change fn.n to fn.value) in the 2nd bit of code) contains the winning entries for simplicity IF you don't mind any missing dates not showing up.
Ok yes. Using a CTE with the UNION ALL operator 2 passes the input table (which is tiny) and expands across the entire series. This code uses LEAD and SELECT TOP to conditionally expand the input rows to include any missing date gap and sets an is_policy 0/1 indicator column. I changed the input data to include a gap. Is it faster? Idk on my machine both Jeff's code and this only take 1ms
drop table if exists #Policy;
go
Create Table #Policy(
PolNumber int,
StartDate date,
EndDate date,
Status varchar(10));
Insert Into #Policy Values
(100,'2023-01-04','2024-02-22','Active')
,(100,'2021-01-04','2022-02-04','InActive')
,(101,'2022-01-01','2022-01-26','Active')
,(102,'2024-02-01','2024-12-16','Active')
,(104,'2023-06-24','2024-05-31','Active');
set statistics time on;
set statistics io on;
with lead_cte as (
select *, lead(StartDate) over (order by StartDate) lead_start_dt
from #Policy
where [Status]='Active')
select v.calc_dt, sum(row_exp.is_policy) active_policies
from lead_cte lc
cross apply (values (iif(lc.lead_start_dt>lc.EndDate, datediff(day, lc.EndDate, lc.lead_start_dt), 0))) calc(gap_days)
cross apply (select top(iif(calc.gap_days>0, 2, 1)) v.day_count, v.is_policy
from (values (datediff(day, lc.StartDate, lc.EndDate), 1),
(calc.gap_days, 0)) v(day_count, is_policy)) row_exp(day_count, is_policy)
cross apply dbo.fnTally(0, row_exp.day_count) fn
cross apply (values (dateadd(day, fn.n, iif(row_exp.is_policy=1, lc.StartDate, lc.EndDate)))) v(calc_dt)
group by v.calc_dt
order by v.calc_dt;
set statistics io off;
set statistics time off;
Aus dem Paradies, das Cantor uns geschaffen, soll uns niemand vertreiben können
February 20, 2024 at 7:10 pm
Jeff Moden wrote:IMHO, Steve Collins' post (with a tiny tweak (change fn.n to fn.value) in the 2nd bit of code) contains the winning entries for simplicity IF you don't mind any missing dates not showing up.
Ok yes. Using a CTE with the UNION ALL operator 2 passes the input table (which is tiny) and expands across the entire series. This code uses LEAD and SELECT TOP to conditionally expand the input rows to include any missing date gap and sets an is_policy 0/1 indicator column. I changed the input data to include a gap. Is it faster? Idk on my machine both Jeff's code and this only take 1ms
drop table if exists #Policy;
go
Create Table #Policy(
PolNumber int,
StartDate date,
EndDate date,
Status varchar(10));
Insert Into #Policy Values
(100,'2023-01-04','2024-02-22','Active')
,(100,'2021-01-04','2022-02-04','InActive')
,(101,'2022-01-01','2022-01-26','Active')
,(102,'2024-02-01','2024-12-16','Active')
,(104,'2023-06-24','2024-05-31','Active');
set statistics time on;
set statistics io on;
with lead_cte as (
select *, lead(StartDate) over (order by StartDate) lead_start_dt
from #Policy
where [Status]='Active')
select v.calc_dt, sum(row_exp.is_policy) active_policies
from lead_cte lc
cross apply (values (iif(lc.lead_start_dt>lc.EndDate, datediff(day, lc.EndDate, lc.lead_start_dt), 0))) calc(gap_days)
cross apply (select top(iif(calc.gap_days>0, 2, 1)) v.day_count, v.is_policy
from (values (datediff(day, lc.StartDate, lc.EndDate), 1),
(calc.gap_days, 0)) v(day_count, is_policy)) row_exp(day_count, is_policy)
cross apply dbo.fnTally(0, row_exp.day_count) fn
cross apply (values (dateadd(day, fn.n, iif(row_exp.is_policy=1, lc.StartDate, lc.EndDate)))) v(calc_dt)
group by v.calc_dt
order by v.calc_dt;
set statistics io off;
set statistics time off;
Maybe you should try with more test data if you want to see which is faster.
February 20, 2024 at 8:42 pm
This reminds me of the good ol' days on these forums... thanks for the memories, folks.
--Jeff Moden
Change is inevitable... Change for the better is not.
March 13, 2024 at 12:58 pm
This was removed by the editor as SPAM
Viewing 4 posts - 16 through 18 (of 18 total)
You must be logged in to reply to this topic. Login to reply