2017-09-15 56 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

相關問題