从 SQL 服务器表中获取的连续行

0 sql-server

我们有以下表格结构

+---------+------------+-------+---------+------------+---------+-----------+----------+--------+
| EmpCode |   InDate   | Shift | ArrTime |  OutDate   | DepTime | HoursWrkd | OverTime | Status |
+---------+------------+-------+---------+------------+---------+-----------+----------+--------+
|     110 | 04/11/2008 | GN    | 9:45    | 04/11/2008 | 0:00    | 0:00      | 0:00     | P P    |
|     115 | 03/11/2008 | GN    | 9:44    | 03/11/2008 | 18:00   | 8:16      | 0:00     | P P    |
|     105 | 03/11/2008 | GN    | 0:00    | 03/11/2008 | 0:00    | 0:00      | 0:00     | A A    |
|     105 | 04/11/2008 | GN    | 0:00    | 03/11/2008 | 0:00    | 0:00      | 0:00     | A A    |
|     110 | 03/11/2008 | GN    | 9:45    | 03/11/2008 | 0:00    | 0:00      | 0:00     | P P    |
|      86 | 29/11/2008 | HD    | 0:00    | 29/11/2008 | 0:00    | 0:00      | 0:00     | HD     |
|     105 | 05/11/2008 | GN    | 9:45    | 04/11/2008 | 0:00    | 0:00      | 0:00     | P P    |
+---------+------------+-------+---------+------------+---------+-----------+----------+--------+
Run Code Online (Sandbox Code Playgroud)

我们想要那些员工连续缺勤两天的记录。天数间隔将是动态的。所以,上面的结果集应该返回

+---------+------------+-------+---------+------------+---------+-----------+----------+--------+
| EmpCode |   InDate   | Shift | ArrTime |  OutDate   | DepTime | HoursWrkd | OverTime | Status |
+---------+------------+-------+---------+------------+---------+-----------+----------+--------+
|     105 | 03/11/2008 | GN    | 0:00    | 03/11/2008 | 0:00    | 0:00      | 0:00     | A A    |
|     105 | 04/11/2008 | GN    | 0:00    | 03/11/2008 | 0:00    | 0:00      | 0:00     | A A    |
+---------+------------+-------+---------+------------+---------+-----------+----------+--------+
Run Code Online (Sandbox Code Playgroud)

任何帮助将是非常可观的。

Han*_*non 7

在不知道动态天数间隔是什么意思的情况下,以下是我如何尝试的示例。

USE tempdb;
GO
CREATE TABLE dbo.ShiftStatii
(
    ShiftStatusID INT NOT NULL 
        CONSTRAINT PK_ShiftStatii 
        PRIMARY KEY CLUSTERED 
        IDENTITY(1,1)
    , StatusName VARCHAR(255) NOT NULL
);

INSERT INTO dbo.ShiftStatii (StatusName) 
VALUES ('Present'), ('Absent'), ('Holiday'); 

CREATE TABLE dbo.Employees
(
    EmpID INT NOT NULL 
        CONSTRAINT PK_Employees 
        PRIMARY KEY CLUSTERED 
        IDENTITY(1,1)
    , EmployeeName VARCHAR(255)
);

INSERT INTO dbo.Employees (EmployeeName) 
VALUES ('John'), ('Jane'), ('Joe');

CREATE TABLE dbo.Shifts
(
    ShiftID INT NOT NULL 
        CONSTRAINT PK_Shifts 
        PRIMARY KEY CLUSTERED 
        IDENTITY(1,1)
    , EmpID INT NOT NULL 
        CONSTRAINT FK_Shifts_EmpID
        FOREIGN KEY REFERENCES dbo.Employees(EmpID) 
        ON UPDATE NO ACTION ON DELETE NO ACTION
    , InDate DATE
    , ShiftStatusID INT NOT NULL 
        CONSTRAINT FK_Shifts_ShiftStatusID
        FOREIGN KEY REFERENCES dbo.ShiftStatii(ShiftStatusID) 
        ON UPDATE NO ACTION ON DELETE NO ACTION
);

INSERT INTO dbo.Shifts (EmpID, InDate, ShiftStatusID) 
VALUES (1, '20130201', 1)
    , (2, '20130201', 2)
    , (3, '20130201', 1)
    , (1, '20130202', 1)
    , (2, '20130202', 2)
    , (3, '20130202', 1)
    , (1, '20130203', 1)
    , (2, '20130203', 1)
    , (3, '20130203', 2)
    , (1, '20130205', 1)
    , (2, '20130205', 3)
    , (3, '20130205', 2);

SELECT E.EmployeeName, S.InDate, SS.StatusName
FROM dbo.Shifts S
    INNER JOIN dbo.Employees E ON S.EmpID = E.EmpID
    INNER JOIN dbo.ShiftStatii SS ON S.ShiftStatusID = SS.ShiftStatusID
ORDER BY E.EmployeeName, S.InDate
Run Code Online (Sandbox Code Playgroud)

因此,我的测试数据是:

在此处输入图片说明

SELECT E.EmployeeName, S1.InDate, S2.InDate
FROM (
        SELECT ROW_NUMBER() 
            OVER (PARTITION BY S.EmpID ORDER BY S.InDate) AS EmpRowNum, *
        FROM dbo.Shifts S) S1
    INNER JOIN (
        SELECT ROW_NUMBER() 
            OVER (PARTITION BY S.EmpID ORDER BY S.InDate) AS EmpRowNum, *
        FROM dbo.Shifts S
        ) S2 ON S1.EmpID = S2.EmpID AND S1.EmpRowNum = S2.EmpRowNum - 1
INNER JOIN dbo.Employees E ON S1.EmpID = E.EmpID
WHERE S1.ShiftStatusID = 2 AND S2.ShiftStatusID = 2
Run Code Online (Sandbox Code Playgroud)

这样做的结果是:

在此处输入图片说明