繁体   English   中英

正确计算 SQL 中的工作日

[英]Calculate correctly the working days in SQL

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

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

在此处输入图像描述

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

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

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

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

在此处输入图像描述

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

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

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;

比较蓝表和绿表的数据结果,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*/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM