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 函数中将其转换为时间
我有一个 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 函数中将其转换为时间