我有一个数据表,每个字符串由4个日期组成:表格示例此外,我还有一张日历表,上面有我所在地的节假日和周末。日历表
我需要的是在数据表中计算以下对的工作日数:
- task_work_end_date和task_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 by
和select
的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)