使用日历表计算数据表中两个日期之间的工作日



我有一个数据表,每个字符串由4个日期组成:表格示例此外,我还有一张日历表,上面有我所在地的节假日和周末。日历表

我需要的是在数据表中计算以下对的工作日数:

  • task_work_end_datetask_got_to_work_date
  • task_got_to_work_date任务分配日期

我尝试过以下选择,但它总是显示1个工作日,因为我把calendar_date放在前面:

select data_table.*, days.work_days 
from data_table
left join (
select calendar_date, count(calendar_date) as work_days
from calendar_table
where type_of_day IN ('workday', 'workday shortened')
group by calendar_date ) days
ON days.calendar_date between task_assigned_date and task_got_to_work_date

请就SQL提供建议,以实现这些表的正确联接。

如果您在SQL server上,则按如下方式使用OUTER APPLY

select d.*, days.work_days 
from data_table d
outer apply (
select count(calendar_date) as work_days
from calendar_table c
where c.type_of_day IN ('workday', 'workday shortened') 
and c.calendar_date between d.task_assigned_date and d.task_got_to_work_date) days

横向连接肯定是解决问题的一种方法(即其他答案中的apply语法(。

一个更通用的答案只是一个相关的子查询:

select d.*, 
(select count(*)
from calendar_table c
where c.type_of_day in ('workday', 'workday shortened') and
c.calendar_date between d.task_assigned_date and d.task_got_to_work_datework_days 
) as work_days
from data_table d;

注意:如果性能是一个问题,可能还有其他方法。如果是这种情况,请接受此处的其中一个答案,并提出问题。

要使用左联接,需要更改分组方式。您还可以在group byselect的data_table中列出实际列。

select data_table.*, count(days.calendar_date)
from data_table
left join calendar_table days
ON days.calendar_date between task_assigned_date and task_got_to_work_date
and type_of_day IN ('workday', 'workday shortened')
group by data_table.*

另一种选择是外部应用并以这种方式获得计数:

select data_table.*, days.work_days 
from data_table
outer apply (
select count(calendar_date) as work_days
from calendar_table
where type_of_day IN ('workday', 'workday shortened')
and calendar_date between task_assigned_date and task_got_to_work_date) days

解决方案在POSTGRES:中非常适合我

table example
join
calendar table ON tsrange(task_assigned_date, task_got_to_work_date)&&tsrange(calendar.start_time, calendar.end_time)

最新更新