SQL Server - 查找缺席日期

时间:2017-06-07 13:53:02

标签: sql sql-server sql-server-2008

我有以下数据集:

在此输入图片说明

以下是此数据的脚本:

;使用数据集AS(     选择'EMP01'AS EMP_ID,CAST('2018-01-01'AS DATE)AS PERIOD_START,CAST('2018-01-31'AS DATE)AS PERIOD_END,CAST('2018-01-07'AS DATE)AS CUT_DATE     联盟     选择'EMP01'AS EMP_ID,CAST('2018-01-01'AS DATE)AS PERIOD_START,CAST('2018-01-31'AS DATE)AS PERIOD_END,CAST('2018-01-15'AS DATE)AS CUT_DATE     联盟     选择'EMP02'作为EMP_ID,CAST('2018-01-01'作为日期)作为PERIOD_START,CAST('2018-01-31'作为日期)AS PERIOD_END,CAST('2018-01-09'作为日期)AS CUT_DATE ) 选择 * 来自数据集 我需要将这些期间(PERIOD_START和PERIOD_END)除以CUT_DATE(不包括那些期间的截止日期)切割日期的数量可以是任意的(3,5,8等)。

期望上述数据集的结果是:

3 个答案:

答案 0 :(得分:2)

如果您的SQL Server版本支持LAG,则可以使用此功能。

SELECT EMPLOYEE_ID,
       ITEM_TYPE,
       MIN(APPLY_DATE) AS STARTDATE,
       MAX(APPLY_DATE) AS ENDDATE
FROM
 (SELECT T.*,
         SUM(CASE WHEN PREV_TYPE=ITEM_TYPE THEN 0 ELSE 1 END) 
         OVER(PARTITION BY EMPLOYEE_ID ORDER BY APPLY_DATE) AS GRP
  FROM (SELECT D.*,
        LAG(ITEM_TYPE) OVER(PARTITION BY EMPLOYEE_ID ORDER BY APPLY_DATE) AS PREV_TYPE
        FROM DATA D
       ) T
  ) T
WHERE ITEM_TYPE IN ('Sickness','Vacation')
GROUP BY EMPLOYEE_ID,ITEM_TYPE,GRP

逻辑是获取前一行的item_type(基于apply_date的升序)并将其与当前行的值进行比较。如果它们相等,则它们属于同一组。否则你开始一个新的团队。这是在sum窗口函数中完成的。分配组后,您只需获取employee_id,item_type的maxmin日期。

Sample Demo

答案 1 :(得分:0)

您将使用LAG功能。 如果按某种顺序排序,LAG函数会给出先前的值;

完整说明可在以下网址找到:http://www.sqlservercentral.com/articles/T-SQL/106783/

查看vkp的完整查询答案

答案 2 :(得分:0)

如果支持滞后,这是另一种方式。 Rextester样品 与tbl一样 (选择d。*     ,(item_type = lag(item_type)结束时的情况(按照employee_id顺序按apply_date分区))             那么0             否则1     结束grp_tmp 来自DATA2 d 哪里     item_type<> '工作' ) ,tbl2为 (选择t。*     ,sum(grp_tmp)结束(按employee_id,apply_date排序                         无界前行和当前行之间的行                         )     作为grp 来自tbl t ) 选择 员工ID     ,物品种类     ,(CONVERT(VARCHAR(24),分钟(APPLY_DATE),103)     +' - '     + CONVERT(VARCHAR(24),最大值(APPLY_DATE),103)     )作为范围 来自tbl2 按EMPLOYEE_ID分组,         物品种类         ,GRP 订购     员工ID     ,分钟(APPLY_DATE); 产量 + ------------- ----------- + + ----------------------- - + | EMPLOYEE_ID | ITEM_TYPE |范围| + ------------- ----------- + + ----------------------- - + | 1 |疾病| 2017/05/23 - 2017/05/24 | | 1 |假期| 2017/05/29 - 29/05/2017 | 1 |疾病| 2017/06/06 - 01/06/2017 | | 2 |疾病| 2017/05/25 - 2017/05/30 | + ------------- ----------- + + ----------------------- - +