2017-09-15 20 views
1

您可以看看下面的任务吗?找到原始开始日期到缺勤期间

DATA表(它包含数据前一周):

CREATE TABLE DATA 
(
EMPLOYEE nvarchar(50), 
ABSENCE_START_DATE datetime, 
ABSENCE_END_DATE datetime, 
ABSENCE_TYPE nvarchar(50) 
) 

ABSENCE_START_DATE - date when absence starts 
ABSENCE_END_DATE - date when absence ends 
ABSENCE_TYPE - type of absence 

当前表包含以下数据:

INSERT INTO DATA(EMPLOYEE,ABSENCE_START_DATE,ABSENCE_END_DATE,ABSENCE_TYPE) VALUES 
('EMP01','2017-09-04 00:00:00.000','2017-09-06 00:00:00.000','Sickness'),--Monday - Wednesday 
('EMP01','2017-09-08 00:00:00.000','2017-09-08 00:00:00.000','Vacation'),--Friday - Friday 
('EMP02','2017-09-04 00:00:00.000','2017-09-09 00:00:00.000','Sickness'),--Monday - Friday 
('EMP03','2017-09-05 00:00:00.000','2017-09-09 00:00:00.000','Sickness')--Tuesday - Friday 

enter image description here

另外,我有另一张桌子 - STORAGE(它包含早于上周开始日期的数据)。

CREATE TABLE STORAGE 
(
EMPLOYEE nvarchar(50), 
APPLY_DATE datetime, 
ABSENCE_TYPE nvarchar(50) 
) 

每天都有记录(不包括周六和周日 - 他们将永远不会在这个表中存在)

INSERT INTO STORAGE(EMPLOYEE,APPLY_DATE,ABSENCE_TYPE) VALUES 
('EMP01','2017-08-27 00:00:00.000','Sickness'), 
('EMP01','2017-08-28 00:00:00.000','Worked'), 
('EMP01','2017-08-29 00:00:00.000','Worked'), 
('EMP01','2017-08-30 00:00:00.000','Sickness'), 
('EMP01','2017-08-31 00:00:00.000','Sickness'), 
('EMP01','2017-09-01 00:00:00.000','Sickness'), 
('EMP02','2017-08-31 00:00:00.000','Worked'), 
('EMP02','2017-09-01 00:00:00.000','Sickness') 

enter image description here

所以,任务: SQL -script应找到原始开始日期到缺席期间(从数据表格),缺席开始日期是星期一

换句话说,脚本应该日复一日地“过去”,找到合适的缺席期开始的日期。

周一没有必要缺席是'生病'。这可能是也“旅游”,“生育” ......

预期结果的例子如下(注意第一和第三行 - 没有开始日期是从数据表中相应的行不同):

enter image description here

预先感谢您。

+0

在存储中,EMP01在2017-08-29上工作,但您的预期结果显示这是他们缺席的开始。是对的吗? –

+0

为什么''emp01'的结果'absence_start_date = 2017-08-29'根据他在同一天工作的'storage'表格?在'emp03'的情况下它的正确性?或相反亦然? – zarruq

+0

是的,对不起,你是对的。我的错 –

回答

0

从共享样本数据,似乎你正在寻找从storage检索mindatedataabsence_start_date列,下面的查询可以是一种选择。

SELECT d.Employee, 
     coalesce(CASE 
        WHEN d.ABSENCE_TYPE = 'Sickness' THEN 
          (SELECT min(apply_date) 
          FROM 
          STORAGE s 
          WHERE s.employee = d.employee 
           AND s.ABSENCE_TYPE = 'Sickness') 
        ELSE d.ABSENCE_START_DATE 
       END,d.ABSENCE_START_DATE) AS ABSENCE_START_DATE, 
     d.ABSENCE_END_DATE, 
     ABSENCE_TYPE 
FROM DATA d; 

更新1: 一个更通用的查询是下面。

SELECT d.Employee, 
     coalesce(
        (SELECT min(apply_date) 
        FROM 
        STORAGE s 
        WHERE s.employee = d.employee 
        AND s.ABSENCE_TYPE = d.ABSENCE_TYPE),d.ABSENCE_START_DATE) AS ABSENCE_START_DATE, 
     d.ABSENCE_END_DATE, 
     d.ABSENCE_TYPE 
FROM DATA d 

更新2: 如果你想排除从数据weekends,下面是查询。

SELECT d.Employee, 
     coalesce(
        (SELECT min(apply_date) 
        FROM 
        STORAGE s 
        WHERE s.employee = d.employee 
        AND s.ABSENCE_TYPE = d.ABSENCE_TYPE 
        AND DATENAME(dw,apply_date) NOT IN('Sunday','Saturday')),d.ABSENCE_START_DATE) AS ABSENCE_START_DATE, 
     d.ABSENCE_END_DATE, 
     d.ABSENCE_TYPE 
FROM DATA d 

结果:

Employee ABSENCE_START_DATE  ABSENCE_END_DATE ABSENCE_TYPE 
-------------------------------------------------------------------- 
EMP01  30.08.2017 00:00:00 06.09.2017 00:00:00 Sickness 
EMP01  08.09.2017 00:00:00 08.09.2017 00:00:00 Vacation 
EMP02  01.09.2017 00:00:00 09.09.2017 00:00:00 Sickness 
EMP03  05.09.2017 00:00:00 09.09.2017 00:00:00 Sickness 

您可以查看演示here

希望这会有所帮助。

+0

您好Zarruq,非常感谢您。是的,它可以工作,但在代码中,您有以下过滤器“ABSENCE_TYPE ='Sickness'”,但周一可能有其他缺席类型。例如。 '旅行','生育'......所以,在这种情况下,代码将不起作用。 –

+0

Zarruq,我不需要从存储的最短日期到数据表的absence_start_date列。例如。在存储员工EMP01具有以下数据: EMP01 2017年8月28日疾病 EMP01 2017年8月29日任职 EMP01二零一七年八月三十零日疾病 EMP01 2017年8月31日疾病 所以,你的代码会发现八月,28日开始缺席,但需要在8月30日 –

+0

@DavidFreeman:更新你的问题。我会更新我的答案。我假设提供的数据有限。在您当前的示例数据上,我的查询起作用。 – zarruq

相关问题