【问题标题】:Calculate correctly the working days in SQL正确计算 SQL 中的工作日
【发布时间】:2021-06-16 02:29:25
【问题描述】:

我有一个包含一些用户 ID 事件的表(起始表)。

在此表中有一个 Event_Id = 1 表示当地假期(不是工作日)。

我需要填写“Event_1”列才能正确计算工作日(结果表 - 如下)。

  • 在 Event_Id 1 的每一行中,Event_1 列应该有 a 1 如果对应的用户作为匹配 Event_Id = 1 之间 StartDate 和 EndDate,否则应为 0。

  • 如果分析中的行 Event_id = 1,则 Event_1 列中的值
    也应该是 0。

我已经有一个计算工作日的函数。

问候, 埃利奥·费尔南德斯

【问题讨论】:

  • 请标记使用哪个数据库平台。你有什么尝试?

标签: sql sql-server-2008


【解决方案1】:

没有。您可以将过滤器移动到on 子句并摆脱子查询:

Select e1.*,
       (Case When e2.StartDate Is not Null and e1.Event_Id = 1 then 0
             When e2.StartDate Is not Null Then 1 
             Else 0
        End) As [Local_Holiday]
From [plann].[Events] e left Join
     [plann].[Events] e2
     on e2.Event_Id = 1 and
        e2.StartDate Between e1.StartDate and e1.EndDate;

【讨论】:

    【解决方案2】:

    我想出了这个解决方案,但我想知道您是否认为这是最好的方法。

    Select T1.*,
        Case
            When t2.StartDate Is not Null and t1.Event_Id = 1 then 0
            When t2.StartDate Is not Null Then 1 
            Else 0
        End As [Local_Holiday]
    From 
        [plann].[Events]  as T1 left Join
        (Select StartDate
            From [plann].[Events] 
            Where Event_Id = 1 ) as T2 ON T2.StartDate Between T1.StartDate and T1.EndDate
    

    【讨论】:

      【解决方案3】:

      比较蓝表和绿表的数据结果,Event_1 的值似乎是分配给“当地假日”的天数。

      如果“本地假期”仅等于一天,并且所有“本地假期”记录适用于假期与假期重合的任何用户,那么 Gordon 的解决方案有效(我喜欢他摆脱子查询的方式)。

      但是,您可能需要解决其他问题。

      根据您的数据结果,在假期期间发生当地假期的每个用户都有单独的记录表明这一点,这意味着每个用户是否存在假期记录很重要。如果是这样,请为 [User Ud] 添加一个附加联接。

      LEFT JOIN plann.Events e2 ON e2.Event_Id = 1 
          AND e2.StartDate BETWEEN e1.StartDate AND e1.EndDate 
          AND e2.[User Ud] = e1.[User Ud]
      

      如果没有 [User Ud] 加入,如果用户 22 在其休假时间内有假期,则该假期被识别——但他的数据结果与其他人相比不一致,因为他没有分配给他的记录Event_Id = 1。

      使用 [User Ud] 加入,您可以获得一致的结果,但这会导致设计问题和限制。

      假设“本地假期”适用于所有用户(典型)。如果是这样,我建议创建一个单独的假期表。访问适用日期的表格可确保为具有适用假期日期范围的所有用户识别所有假期。

      我修改了脚本,删除了假期总是一天的假设(加拿大、英国和其他国家/地区连续有两个公共假期)。这种考虑使我重新使用子查询。

      SELECT
          e1.[User Ud],
          e1.Event_Id,
          e1.Event,
          e1.StartDate,
          e1.EndDate,
          CASE
              WHEN e1.Event_Id = 1
              THEN 0
              WHEN e2.[User Ud] IS NOT NULL
              THEN Number_Days
              ELSE 0
          END AS Holiday_Nmbr_Days,
          WorkingDays
      
      FROM plann.Events e1
      
      LEFT JOIN
          (SELECT
              [User Ud],
              DATEDIFF(dd,StartDate,EndDate) + 1 AS Number_Days,
              StartDate
          FROM plann.Events
          WHERE Event_Id = 1) AS e2 ON e2.Startdate BETWEEN e1.Startdate AND e1.EndDate
              AND e2.[User Ud] = e1.[User Ud] /*Exclude if not applicable*/
      

      【讨论】:

      • 黎明,我明白你在说什么。此示例只是主表事件的一个子集。我有一张所有国家假期的表,向所有人报告,因为业务遍布全国,当地假期向用户工作的圣日报告,所以我决定将这个假期视为一个事件,就像假期和很多其他的。在示例中,我选择不为 User_Id 22 放置本地假期,但我可以放置。谢谢。
      猜你喜欢
      • 2016-02-20
      • 2021-05-09
      • 2023-03-19
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 2010-09-25
      相关资源
      最近更新 更多