找到原始开始日期到缺席期

时间:2017-09-15 10:49:15

标签: sql sql-server sql-server-2012

请您查看以下任务?

我有 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应该找到缺席时间的原始开始日期(来自DATA表)缺勤开始日期星期一

换句话说,脚本应该日复一日地过去"过去"并在适当的缺勤期开始时找到日期。

没有必要在星期一缺席'疾病'。它也可能是“旅行”,“孕妇”......

以下示例的预期结果是(注意第一行和第三行 - 缺勤开始日期与DATA表中的适当行不同):

enter image description here

提前谢谢。

1 个答案:

答案 0 :(得分:0)

从共享的示例数据中,您似乎希望从查询下方的min表的datestorage列中检索absence_start_date data可以选择。

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

希望这会有所帮助。