正确计算 SQL 中的工作日

Calculate correctly the working days in SQL

我有这个 table 和一些用户 ID 事件(开始 table)。

在这个 table 中有一个 Event_Id = 1 指的是当地假日(不是工作日)。

我需要填写 'Event_1' 栏才能正确计算工作日(结果 table - 下面).

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

此致, 埃里奥·费尔南德斯

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

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

没有。您可以将过滤器移动到 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;

比较蓝色 table 和绿色 table 的数据结果,Event_1 的值似乎是分配给“Local Holiday”的天数。

如果“本地假期”永远只等于一天,并且所有“本地假期”记录都适用于假期与假期重合的任何用户,那么 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] 加入,您会得到一致的结果,但这会导致设计问题和限制。

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

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

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*/