首页 > 解决方案 > Datediff 不包括周末

问题描述

我有一个查询计算两个日期之间的周转时间、天数差。日期在申请批准的业务流程中。

因此,如果第一个用户在星期五批准申请,下一个用户在星期一批准,则预期 TAT 为 1。

我已经设法实现了这个结果,除了在一个罕见的情况下,两个批准都在周末完成,返回的 TAT 为 -1,如下所示:

在此处输入图像描述

我希望它返回 0 的 TAT。

以下是我的 datediff 计算:

SELECT STEP_ONE, STEP_TWO,

(DATEDIFF(dd, STEP_ONE,STEP_TWO))
  -(DATEDIFF(wk, STEP_ONE,STEP_TWO) * 2)
  -(case datepart(dw, STEP_ONE)+@@datefirst when 8 then 1 else 0 end) 
  -(case datepart(dw, STEP_TWO)+@@datefirst when 7 then 1 when 14 then 1 else 0 end)
  AS TAT 

FROM TEST_1

标签: sqlsql-servertsql

解决方案


此方法检查 TAT 是否为负,如果是,则返回 0:

SELECT STEP_ONE, STEP_TWO,

IIF (
        (DATEDIFF(dd, STEP_ONE,STEP_TWO))
        -(DATEDIFF(wk, STEP_ONE,STEP_TWO) * 2)
        -(case datepart(dw, STEP_ONE)+@@datefirst when 8 then 1 else 0 end) 
        -(case datepart(dw, STEP_TWO)+@@datefirst when 7 then 1 when 14 then 1 else 0 end)
        <= 0,
        0,
        (DATEDIFF(dd, STEP_ONE,STEP_TWO))
        -(DATEDIFF(wk, STEP_ONE,STEP_TWO) * 2)
        -(case datepart(dw, STEP_ONE)+@@datefirst when 8 then 1 else 0 end) 
        -(case datepart(dw, STEP_TWO)+@@datefirst when 7 then 1 when 14 then 1 else 0 end)
    ) AS TAT 

FROM TEST_1

这两个 4 行的长表达式每个都与您编写的相同。

编辑:要使条件仅影响在周末计算的 TAT(正如您在下面的评论中所要求的),您可以将 IIF 包装在另一个询问周末的 IIF 中。这是产生的更长的查询:

SELECT STEP_ONE, STEP_TWO,

IIF (@@DATEFIRST = 1 AND (DatePart(dw, STEP_ONE) > 5 OR DatePart(dw, STEP_TWO) > 5)
  OR @@DATEFIRST = 7 AND (DatePart(dw, STEP_ONE) IN (1, 7) OR DatePart(dw, STEP_TWO) IN (1, 7)),

    IIF (
            (DATEDIFF(dd, STEP_ONE,STEP_TWO))
            -(DATEDIFF(wk, STEP_ONE,STEP_TWO) * 2)
            -(case datepart(dw, STEP_ONE)+@@datefirst when 8 then 1 else 0 end) 
            -(case datepart(dw, STEP_TWO)+@@datefirst when 7 then 1 when 14 then 1 else 0 end)
            <= 0,
            0,
            (DATEDIFF(dd, STEP_ONE,STEP_TWO))
            -(DATEDIFF(wk, STEP_ONE,STEP_TWO) * 2)
            -(case datepart(dw, STEP_ONE)+@@datefirst when 8 then 1 else 0 end) 
            -(case datepart(dw, STEP_TWO)+@@datefirst when 7 then 1 when 14 then 1 else 0 end
        )),
    (DATEDIFF(dd, STEP_ONE,STEP_TWO))
    -(DATEDIFF(wk, STEP_ONE,STEP_TWO) * 2)
    -(case datepart(dw, STEP_ONE)+@@datefirst when 8 then 1 else 0 end) 
    -(case datepart(dw, STEP_TWO)+@@datefirst when 7 then 1 when 14 then 1 else 0 end)
) AS TAT 

FROM TEST_1

推荐阅读