列表使用自加入的员工工作的分钟数
List No of minutes worked by an employee using self join
我有一个 SQL 服务器 table emp_swipe_rec,它只有 6 列。我想知道员工 A 和 B 今天(过去 24 小时)工作了多少时间(以分钟为单位)。员工 A 当天已经刷完卡了。员工 B 仍在工作。我们不会为滑动 in/swipe 存储两个不同的列。我们使用 swipe_type(I - In/O- Out)来确定员工仍在工作或刷出。
我需要查询的两个输出。
过去 24 小时刷卡的每位员工的总工作分钟数。 (在过去的 24 小时内都刷 in/swipe 员工)
现在正在工作的员工列表以及他们的总工作分钟数,直到他们刷入。(过去 24 小时只刷入不刷出)
Employee_ID
Employee_Name
Swipe_Type
Swipe_In_Out_Time
Department
Emp_Swipe_Rec_PK
1
A
I
2021-03-07 08:00:00.000
MARKETING
1
2
B
I
2021-03-07 08:00:00.000
SALES
2
1
A
O
2021-03-07 15:00:00.000
MARKETING
3
我尝试了以下查询,但它说:
invalid column name for starttime and endtime param inside the DATEDIFF row.
我不知道我做错了什么。
SELECT one.EMPLOYEE_ID,one.EMPLOYEE_NAME
one.SWIPE_IN_OUT_TIME AS starttime,
two.SWIPE_IN_OUT_TIME AS endtime,
DATEDIFF(minute,starttime,endtime) AS diff
FROM emp_swipe_rec one
INNER JOIN emp_swipe_rec two ON two.SWIPE_TYPE <> one.SWIPE_TYPE
WHERE one.Employee_Id = two.Employee_Id AND one.Department = two.Department
我认为这满足了您的第一个要求“过去 24 小时内每个刷卡员工的总工作分钟数”
这 returns 员工 1 的一条记录,因为他是唯一退出的员工(2021 年 8 月!?)
由于这使用了window函数,您需要使用SQL Server 2012或更高版本,您已经标记了2008和2012
;WITH SwipeIns AS
(
SELECT Employee_ID,
Employee_Name,
Swipe_In_Out_Time
FROM emp_swipe_rec
WHERE Swipe_Type = 'I' AND
Swipe_In_Out_Time > DATEADD(HOUR,-24,GETDATE()) AND
Swipe_In_Out_Time < GETDATE()
),
SwipeOuts AS
(
SELECT Employee_ID,
Swipe_In_Out_Time
FROM emp_swipe_rec
WHERE Swipe_Type = 'O' AND
Employee_ID IN (SELECT Employee_ID FROM SwipeIns) AND
Swipe_In_Out_Time > DATEADD(HOUR,-24,GETDATE())
)
SELECT Employee_ID,
Employee_Name,
SwipeIn,
SwipeOut,
DATEDIFF(MINUTE,SwipeIn,SwipeOut) AS Duration
FROM (
SELECT i.Employee_ID,
i.Employee_Name,
i.Swipe_In_Out_Time AS SwipeIn,
o.Swipe_In_Out_Time AS SwipeOut,
ROW_NUMBER() OVER (PARTITION BY i.Employee_ID ORDER BY o.Swipe_In_Out_Time) AS RowN
FROM SwipeIns i
JOIN SwipeOuts o
ON i.Employee_ID = o.Employee_ID
) a
WHERE RowN = 1
另外,为什么你的 table 没有标准化?您没有员工 table 吗? EmployeeName 和 Department 是多余的
我有一个 SQL 服务器 table emp_swipe_rec,它只有 6 列。我想知道员工 A 和 B 今天(过去 24 小时)工作了多少时间(以分钟为单位)。员工 A 当天已经刷完卡了。员工 B 仍在工作。我们不会为滑动 in/swipe 存储两个不同的列。我们使用 swipe_type(I - In/O- Out)来确定员工仍在工作或刷出。
我需要查询的两个输出。 过去 24 小时刷卡的每位员工的总工作分钟数。 (在过去的 24 小时内都刷 in/swipe 员工) 现在正在工作的员工列表以及他们的总工作分钟数,直到他们刷入。(过去 24 小时只刷入不刷出)
Employee_ID | Employee_Name | Swipe_Type | Swipe_In_Out_Time | Department | Emp_Swipe_Rec_PK |
---|---|---|---|---|---|
1 | A | I | 2021-03-07 08:00:00.000 | MARKETING | 1 |
2 | B | I | 2021-03-07 08:00:00.000 | SALES | 2 |
1 | A | O | 2021-03-07 15:00:00.000 | MARKETING | 3 |
我尝试了以下查询,但它说:
invalid column name for starttime and endtime param inside the DATEDIFF row.
我不知道我做错了什么。
SELECT one.EMPLOYEE_ID,one.EMPLOYEE_NAME
one.SWIPE_IN_OUT_TIME AS starttime,
two.SWIPE_IN_OUT_TIME AS endtime,
DATEDIFF(minute,starttime,endtime) AS diff
FROM emp_swipe_rec one
INNER JOIN emp_swipe_rec two ON two.SWIPE_TYPE <> one.SWIPE_TYPE
WHERE one.Employee_Id = two.Employee_Id AND one.Department = two.Department
我认为这满足了您的第一个要求“过去 24 小时内每个刷卡员工的总工作分钟数”
这 returns 员工 1 的一条记录,因为他是唯一退出的员工(2021 年 8 月!?)
由于这使用了window函数,您需要使用SQL Server 2012或更高版本,您已经标记了2008和2012
;WITH SwipeIns AS
(
SELECT Employee_ID,
Employee_Name,
Swipe_In_Out_Time
FROM emp_swipe_rec
WHERE Swipe_Type = 'I' AND
Swipe_In_Out_Time > DATEADD(HOUR,-24,GETDATE()) AND
Swipe_In_Out_Time < GETDATE()
),
SwipeOuts AS
(
SELECT Employee_ID,
Swipe_In_Out_Time
FROM emp_swipe_rec
WHERE Swipe_Type = 'O' AND
Employee_ID IN (SELECT Employee_ID FROM SwipeIns) AND
Swipe_In_Out_Time > DATEADD(HOUR,-24,GETDATE())
)
SELECT Employee_ID,
Employee_Name,
SwipeIn,
SwipeOut,
DATEDIFF(MINUTE,SwipeIn,SwipeOut) AS Duration
FROM (
SELECT i.Employee_ID,
i.Employee_Name,
i.Swipe_In_Out_Time AS SwipeIn,
o.Swipe_In_Out_Time AS SwipeOut,
ROW_NUMBER() OVER (PARTITION BY i.Employee_ID ORDER BY o.Swipe_In_Out_Time) AS RowN
FROM SwipeIns i
JOIN SwipeOuts o
ON i.Employee_ID = o.Employee_ID
) a
WHERE RowN = 1
另外,为什么你的 table 没有标准化?您没有员工 table 吗? EmployeeName 和 Department 是多余的