【问题标题】:Counting working days between two dates in data table using calendar table使用日历表计算数据表中两个日期之间的工作日
【发布时间】:2021-01-12 11:08:04
【问题描述】:

我有一个数据表,每个字符串包含 4 个日期: table example 我也有我所在位置的假期和周末日历表。 calendar table

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

  • task_work_end_datetask_got_to_work_date
  • task_got_to_work_datetask_assigned_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 date calendar


    【解决方案1】:

    如果您在 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
    

    【讨论】:

      【解决方案2】:

      横向连接绝对是解决问题的一种方法(即其他答案中的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;
      

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

      【讨论】:

        【解决方案3】:

        要使用左联接,您需要更改分组方式。您也可以在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
        

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 2018-08-03
            • 2010-09-20
            • 2018-10-02
            • 1970-01-01
            • 2014-10-20
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多