Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用T-SQL将行标记为长期疾病?_Sql_Sql Server_Tsql_Gaps And Islands - Fatal编程技术网

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

如何使用T-SQL将行标记为长期疾病?,sql,sql-server,tsql,gaps-and-islands,Sql,Sql Server,Tsql,Gaps And Islands,我有一个挑战。我们的公司想知道员工的病假是否是长期的。因此,如果疾病是30个并发日的一部分,则所有30个或更多记录都应标记为[长期疾病]=真 病假只有星期一到星期五 我有一个表格,每个员工生病的每个日历日都有一行,如下所示: 这甚至可以用T-SQL解决吗?所以这里有一个简单的解决方案 我为每个日历日(s或w)生成一个病假或健康表 然后,我每天都计算过去30个日历日内的非病假天数,周末除外 如果在这段时间里有0个好日子,那么它就是长期疾病,所以我们每天向前看29天,看看我们是否在接下来的30天里

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

病假只有星期一到星期五

我有一个表格,每个员工生病的每个日历日都有一行,如下所示:


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

所以这里有一个简单的解决方案

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

然后,我每天都计算过去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

请阅读一些关于改进您的问题的提示。具有DDL的可用样本数据和预期结果是一个开始。你试过什么?当然有可能。这是一个缺口和孤岛问题,寻找这个,有很多例子可以找到。自己试一试,如果你有问题可以寻求帮助。听起来像是家庭作业问题?实际上,你需要一个日期表,不包括节假日。您可以执行类似于ROW_NUMBER()的操作,也可以在work days表中增加id。返回工作日表,其中当前行的行号或id为+29。这将为您提供每个30天期间的日期范围。然后,您可以链接到病假表,并计算该日期范围内的行数,看看它是否为30。谢谢-我真的可以使用它:-)