so let's assume the following table
create volatile table vt_dates
as
(
select c1.calendar_Date from_dt, c2.calendar_date to_dt
from sys_calendar.calendar c1
cross join
sys_calendar.calendar c2
where c1.calendar_Date between current_date - 30 and current_Date
and c2.calendar_Date between current_date - 30 and current_Date
and c2.calendar_date > c1.calendar_date
) with data primary index (from_dt)
on commit preserve rows;
You have two choices:
1. simple logic but join on calendar table
select from_dt,
to_dt,
sum(case when c.day_of_week in (1,7) then 0 else 1 end) - (case when sum(case when c.day_of_week in (1,7) then 0 else 1 end) = 0 then 0 else 1 end) as count_of_weekdays
from vt_dates v
join sys_calendar.calendar c
on c.calendar_Date between v.from_dt and v.to_dt
group by 1,2
order by 1,2
2. direct calculation with not too obvious formula
select from_dt,
to_dt,
case when day_of_week(from_dt) = 7 then 2
when day_of_week(from_dt) = 1 then 1
else 0
end + from_dt as next_work_dt,
case when day_of_week(to_dt) = 7 then -1
when day_of_week(to_dt) = 1 then -2
else 0
end + to_dt as prev_work_dt,
(prev_work_dt - next_work_dt)+1 as diff,
(case when diff mod 7 = 0 then 1 else 0 end) as correct_fw,
(diff - diff mod 7) / 7 as full_week,
case when diff < 0
then 0
else diff - (full_week*2) - 1
end +
case when day_of_week(prev_work_dt) < day_of_week(next_work_dt)
then -2
else 0
end +
case when diff mod 7 = 0 then 2 else 0 end
as num_of_weekdays
from vt_dates v
order by 1,2
If your table is big and the number of workdays can also be big it might be worth to consider solution two.
A SQL UDF might be usefull to have a central logic for it - even if the UDF code becomes more unreadable due to repeating cases...
↧