如何使用 T-SQL 将行标记为长期疾病?

How do I mark rows as longterm illness using T-SQL?

我有一个挑战。我们的企业想知道员工病假是否是长期病假。因此,如果疾病是 30 个并发日的一部分,则所有 30 个或更多记录应标记为 [long term illness] = True

病假只有周一到周五

我有一个 table,每个员工在他们生病的每个日历日都有一行,如下所示:

这甚至可以用 T-SQL 解决吗?

所以这是一个简单的解决方案。

我为每个日历日(s 或 w)生成一个 table 生病或健康

然后我计算过去 30 个日历日(不包括周末)中没有生病的每一天。

如果那个时期有0个好日子,那就是长期病,所以我们每天向前看29天,看看我们是否在接下来的30天内隐藏了长期病。 如果是病假,在接下来的29天内我们会隐藏一段时间身体不好,那么病假就是长期病的一部分。

在我的示例中,第二周是生病的一周,没有标记,四月和五月是生病的月份,所有的日子都被标记为长期

WITH dates AS /* Generate som dates */
(
    SELECT CAST(DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY (SELECT 1 n))-1, '2020-01-01') AS DATE) dato
    FROM (VALUES (0), (1), (2), (3), (4)) a (b)
       , (VALUES (0), (1), (2), (3), (4)) b (b)
       , (VALUES (0), (1), (2), (3), (4)) c (b)
),
CTE AS /* Set 2nd week and 3,4 month as sick */
(
    SELECT IIF(MONTH(dato) IN (3, 4) OR DATEPART(WEEK, dato) = 2, 's', 'w') state
         , dato
    FROM dates
),
sums AS /* count days of work last 30 days current day included */
(
    SELECT dato
         , State
         , SUM(IIF(State = 'w' AND DATEPART(WEEKDAY, dato) NOT IN (1, 7), 1, 0)) OVER (ORDER BY dato ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) NonSickDays
    FROM CTE
),
periods AS /* Check if no well days for any day in the next 30 days, current day included */
(
    SELECT dato
         , State
         , MIN(NonSickDays) OVER (ORDER BY dato ROWS BETWEEN CURRENT ROW AND 29 FOLLOWING) Minperiod
         , NonSickDays
    FROM sums
)
SELECT dato /* id sick day, and minimum well days is 0 then its a long term day */
     , State
     , IIF(State = 's' AND Minperiod = 0, 'l', '') longtimesick
     , NonSickDays
FROM periods