sql server 中的先进后出

FirstIn and LastOut in sqlserver

我有一个 table 名字 [EmployeeAttendance],并且我在其中有相应顺序的记录。

SELECT EI.[FirstName]+' '+EI.[LastName] [EmployeeName], [Dpt].[FullName] [Department], [Desig].[FullName] [Designation], FirstIN   = CAST(MIN([AttendanceTimeIn]) AS TIME), LastOUT   = CAST(MAX([AttendanceTimeOut]) AS TIME), HoursSpent = DATEDIFF(HOUR, CAST(MIN(AttendanceTimeIn) AS TIME), CAST(MAX(AttendanceTimeOut) AS TIME))  
FROM [HRM].[tbl_EmployeeInfo] [EI],  [HRM].[tbl_Designation] [Desig], [HRM].[tbl_Department] [Dpt], [HRM].[tbl_EmployeeAttendance] [Attendance]
WHERE [Dpt].[ID] = [EI].[DeptCode] AND [Desig].[ID] = [EI].[DesignationCode] AND [Attendance].[EmpCode] = [EI].[ID] AND [EI].[RecordStatusCode] != '13'
AND CAST([AttendanceTimeIn] as date) = CAST(GetDate()-1 as Date)
GROUP BY
EI.[FirstName]+' '+EI.[LastName], [Dpt].[FullName], [Desig].[FullName], CAST([Attendance].[AttendanceTimeIn] AS DATE)

这就是我得到的输出。

Ajmal John      Projects            Project Associate   10:16:38.0000000    NULL    NULL
Asif Asif       Office Staff        Office Boy               09:28:36.0000000   NULL    NULL
Muhammad Asim   Support             Database Support Engineer 10:47:28.0000000  19:16:17.0000000    9
Sajjad Ahmed    Projects            Project Manager          09:41:34.0000000   NULL    NULL
Sidra Khizar    Quality Assurance   SQA Engineer        10:18:48.0000000    NULL    NULL

因为我将 TimeIn 和 TimeOut 放在同一行,所以它给我超时,但对于其他字段,我在第二行有超时,所以它给出 Null。不知道为什么

如果 TimeIn 和 TimeOut 是 TIME 数据类型,那么这有效

DECLARE @EmployeeAttendance TABLE (EmpID INT, TimeIn TIME, [TimeOut] TIME);

INSERT INTO @EmployeeAttendance
(EmpID, TimeIn, TimeOut)
SELECT 1, '9:00', NULL UNION ALL
SELECT 1, NULL, '11:00' UNION ALL
SELECT 1, '11:30', NULL  UNION ALL
SELECT 1, NULL,'13:00' UNION ALL
SELECT 1,'13:30', NULL  UNION ALL
SELECT 1,NULL,'18:00';

SELECT
    EmpID
    , FirstIN   = MIN([TimeIn])
    , LastOUT   = MAX([TimeOut])
    , HoursSpent = DATEDIFF(HOUR, MIN(TimeIn), MAX(TimeOut))
    --, MAX([TimeOut])-MIN([TimeIn]) AS HoursSpent
FROM
    @EmployeeAttendance
GROUP BY
    EmpID;

输出

如果列是 DATETIME 那么试试这个

DECLARE @EmployeeAttendance TABLE (EmpID INT, TimeIn DATETIME, [TimeOut] DATETIME);

INSERT INTO @EmployeeAttendance
(EmpID, TimeIn, TimeOut)
SELECT 1, '9:00', NULL UNION ALL
SELECT 1, NULL, '11:00' UNION ALL
SELECT 1, '11:30', NULL  UNION ALL
SELECT 1, NULL,'13:00' UNION ALL
SELECT 1,'13:30', NULL  UNION ALL
SELECT 1,NULL,'18:00';

SELECT
    EmpID
    , FirstIN   = CAST(MIN([TimeIn]) AS TIME)
    , LastOUT   = CAST(MAX([TimeOut]) AS TIME)
    , HoursSpent = DATEDIFF(HOUR, CAST(MIN(TimeIn) AS TIME), CAST(MAX(TimeOut) AS TIME))
    --, MAX([TimeOut])-MIN([TimeIn]) AS HoursSpent
FROM
    @EmployeeAttendance
GROUP BY
    EmpID;

如果您在 SQL 服务器中有 TimeIn & TimeOut 作为 DateTime 字段,则可以按如下方式实现:

SELECT
  EmpID, 
  MIN(cast(TimeIN as time)) as FirstIN,
  MAX(cast(TimeOut as time)) as LastOUT,
  DATEDIFF(hour,MIN([TimeIn]),MAX([TimeOut])) AS HoursSpent
FROM [EmployeeAttendance]
GROUP BY EmpId

上述示例数据的查询输出如下:

EmpID   FirstIN             LastOUT             HoursSpent
1       09:00:00.0000000    18:00:00.0000000    9

如果您的数据类型是 TIME,那么这可以正常工作

DECLARE @T TABLE 
    ([EmpID] int, [TimeIn] TIME, [TimeOut] TIME)
;

INSERT INTO @T
    ([EmpID], [TimeIn], [TimeOut])
VALUES
    (1, '9:00', NULL),
    (1, NULL, '11:00'),
    (1, '11:30', NULL),
    (1, NULL, '13:00'),
    (1, '13:30', NULL),
    (1, NULL, '18:00')
;
;WITH TM
AS
(
SELECT
    EmpID, 
    MIN([TimeIn]) as StartTime,
    MAX([TimeOut]) as EndTime
    FROM @T
    GROUP BY EmpId
)
SELECT
    *,
    HoursSpent = DATEDIFF(HOUR, StartTime, EndTime)
    FROM TM

结果

如果数据类型不同,请尝试在 MAX 和 MIN 函数中将其转换为时间