如何获取每个员工每天的第一个和最后一个数据
How to get first and last data on each day per employee
嗨,我正在尝试编写一个查询,它会给我输出
每天先入后出的用户 reader 姓名不是 Locker 并确定他是迟到还是早出
示例数据:
EVENTID USERID DATE_TIME READERID READERNAME SNAME LOGTYPE USERNAME RESULT REMARKS DURATION
177792329 50078 2020-01-02 05:45:34 544381431 LOCKER RF-T-33 [IN] IN SUBIA, MAY
177792497 50078 2020-01-02 05:45:50 544343461 SENSORS RF-T-19 [IN] IN SUBIA, MAY
177813432 50078 2020-01-02 06:35:51 544352385 SENSORS RF-T-20 [OUT] OUT SUBIA, MAY
177813495 50078 2020-01-02 06:36:13 544381436 LOCKER RF-T-36 [OUT] OUT SUBIA, MAY
177950118 50078 2020-01-03 05:50:48 544352385 SENSORS RF-T-20 [OUT] OUT SUBIA, MAY
177954602 50078 2020-01-03 05:54:11 544381436 LOCKER RF-T-36 [OUT] OUT SUBIA, MAY
177967366 50078 2020-01-03 06:07:25 544381431 LOCKER RF-T-33 [IN] IN SUBIA, MAY 00:13 13
177967448 50078 2020-01-03 06:07:38 544343461 SENSORS RF-T-19 [IN] IN SUBIA, MAY
177977184 50078 2020-01-03 08:02:59 544352385 SENSORS RF-T-20 [OUT] OUT SUBIA, MAY
177977214 50078 2020-01-03 08:03:21 544381436 LOCKER RF-T-36 [OUT] OUT SUBIA, MAY
177979653 50078 2020-01-03 08:23:54 544381431 LOCKER RF-T-33 [IN] IN SUBIA, MAY 00:20 20
预期输出
先入
USERNAME DATE_TIME First_IN_Time
SUBIA, MAY 2020-01-02 05:45:50 05:45:34
SUBIA, MAY 2020-01-03 05:45:50 06:07:25
最后一个
USERNAME DATE_TIME last_out_Time
SUBIA, MAY 2020-01-02 06:35:51 06:35:51
SUBIA, MAY 2020-01-03 05:45:50 08:02:59
tblshift
SHIFTCODE DATESHIFT STARTSHIFT ENDSHIFT ISRESTDAY
50078 1/24/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 1/25/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 1/26/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 1/27/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 2/10/2020 1/1/1970 10:00:00.000000 PM 1/1/1970 6:00:00.000000 AM 0
50078 2/11/2020 1/1/1970 10:00:00.000000 PM 1/1/1970 6:00:00.000000 AM 0
50078 2/12/2020 1/1/1970 10:00:00.000000 PM 1/1/1970 6:00:00.000000 AM
我有什么尝试
Select
max(A.DATE_TIME) keep (dense_rank first order by A.DATE_TIME) first_IN,
--Max(A.DATE_TIME) first_IN,
A.USERNAME
--min (A.DATE_TIME ) first_IN, max (A.DATE_TIME ) last_out,A.USERNAME
--case
--end
from tblaccesslogs a
where A.LOGTYPE = 'IN' and A.READERNAME <> 'LOCKER'
group by A.USERNAME
更新
我需要确定员工是否早退
基于 table tblshift
希望有人能帮我解决这个问题。
您可以使用 aggregate
函数在单个查询中获取上下班时间,如下所示,并将其与理想的班次开始时间进行比较,如下所示:
SELECT
T.USERNAME,
CASE
WHEN FIRST_IN_TIME >
TRUNC(FIRST_IN_TIME) + ( STARTSHIFT - DATE '1970-01-01' ) THEN 'LATE'
ELSE 'ONTIME'
END AS IN_STATUS
FROM
(
SELECT
A.USERNAME,
A.USERID,
TRUNC(A.DATE_TIME) AS DATE_TIME,
MIN(CASE WHEN A.LOGTYPE = 'IN' THEN A.DATE_TIME END) AS FIRST_IN_TIME,
MAX(CASE WHEN A.LOGTYPE = 'OUT' THEN A.DATE_TIME END) AS LAST_OUT_TIME
FROM TBLACCESSLOGS A
WHERE A.READERNAME <> 'LOCKER'
GROUP BY A.USERNAME, A.USERID, TRUNC(A.DATE_TIME)
) T
JOIN TBLSHIFTS S ON T.USERID = S.SHIFTCODE AND TRUNC(T.DATE_TIME) = TRUNC(S.DATESHIFT);
干杯!!
使用ROW_NUMBER
解析函数:
create table tblaccesslogs (
EVENTID,
USERID,
DATE_TIME,
READERID,
READERNAME,
SNAME,
LOGTYPE,
USERNAME
) AS
SELECT 177792329, 50078, DATE '2020-01-02' + INTERVAL '05:45:34' HOUR TO SECOND, 544381431, 'LOCKER', 'RF-T-33', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177792497, 50078, DATE '2020-01-02' + INTERVAL '05:45:50' HOUR TO SECOND, 544343461, 'SENSORS', 'RF-T-19', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177813432, 50078, DATE '2020-01-02' + INTERVAL '06:35:51' HOUR TO SECOND, 544352385, 'SENSORS', 'RF-T-20', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177813495, 50078, DATE '2020-01-02' + INTERVAL '06:36:13' HOUR TO SECOND, 544381436, 'LOCKER', 'RF-T-36', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177950118, 50078, DATE '2020-01-03' + INTERVAL '05:50:48' HOUR TO SECOND, 544352385, 'SENSORS', 'RF-T-20', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177954602, 50078, DATE '2020-01-03' + INTERVAL '05:54:11' HOUR TO SECOND, 544381436, 'LOCKER', 'RF-T-36', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177967366, 50078, DATE '2020-01-03' + INTERVAL '06:07:25' HOUR TO SECOND, 544381431, 'LOCKER', 'RF-T-33', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177967448, 50078, DATE '2020-01-03' + INTERVAL '06:07:38' HOUR TO SECOND, 544343461, 'SENSORS', 'RF-T-19', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177977184, 50078, DATE '2020-01-03' + INTERVAL '08:02:59' HOUR TO SECOND, 544352385, 'SENSORS', 'RF-T-20', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177977214, 50078, DATE '2020-01-03' + INTERVAL '08:03:21' HOUR TO SECOND, 544381436, 'LOCKER', 'RF-T-36', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177979653, 50078, DATE '2020-01-03' + INTERVAL '08:23:54' HOUR TO SECOND, 544381431, 'LOCKER', 'RF-T-33', 'IN', 'SUBIA, MAY' FROM DUAL;
然后:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY USERNAME, LOGTYPE, TRUNC( DATE_TIME )
ORDER BY DATE_TIME ASC
) AS first_date_time_rn
FROM tblaccesslogs t
WHERE READERNAME <> 'LOCKER'
)
WHERE logtype = 'IN'
AND first_date_time_rn = 1
输出:
EVENTID | USERID | DATE_TIME | READERID | READERNAME | SNAME | LOGTYPE | USERNAME | FIRST_DATE_TIME_RN
--------: | -----: | :------------------ | --------: | :--------- | :------ | :------ | :--------- | -----------------:
177792497 | 50078 | 2020-01-02 05:45:50 | 544343461 | SENSORS | RF-T-19 | IN | SUBIA, MAY | 1
177967448 | 50078 | 2020-01-03 06:07:38 | 544343461 | SENSORS | RF-T-19 | IN | SUBIA, MAY | 1
和:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY USERNAME, LOGTYPE, TRUNC( DATE_TIME )
ORDER BY DATE_TIME DESC
) AS last_date_time_rn
FROM tblaccesslogs t
WHERE READERNAME <> 'LOCKER'
)
WHERE logtype = 'OUT'
AND last_date_time_rn = 1
输出:
EVENTID | USERID | DATE_TIME | READERID | READERNAME | SNAME | LOGTYPE | USERNAME | LAST_DATE_TIME_RN
--------: | -----: | :------------------ | --------: | :--------- | :------ | :------ | :--------- | ----------------:
177813432 | 50078 | 2020-01-02 06:35:51 | 544352385 | SENSORS | RF-T-20 | OUT | SUBIA, MAY | 1
177977184 | 50078 | 2020-01-03 08:02:59 | 544352385 | SENSORS | RF-T-20 | OUT | SUBIA, MAY | 1
db<>fiddle here
嗨,我正在尝试编写一个查询,它会给我输出
每天先入后出的用户 reader 姓名不是 Locker 并确定他是迟到还是早出
示例数据:
EVENTID USERID DATE_TIME READERID READERNAME SNAME LOGTYPE USERNAME RESULT REMARKS DURATION
177792329 50078 2020-01-02 05:45:34 544381431 LOCKER RF-T-33 [IN] IN SUBIA, MAY
177792497 50078 2020-01-02 05:45:50 544343461 SENSORS RF-T-19 [IN] IN SUBIA, MAY
177813432 50078 2020-01-02 06:35:51 544352385 SENSORS RF-T-20 [OUT] OUT SUBIA, MAY
177813495 50078 2020-01-02 06:36:13 544381436 LOCKER RF-T-36 [OUT] OUT SUBIA, MAY
177950118 50078 2020-01-03 05:50:48 544352385 SENSORS RF-T-20 [OUT] OUT SUBIA, MAY
177954602 50078 2020-01-03 05:54:11 544381436 LOCKER RF-T-36 [OUT] OUT SUBIA, MAY
177967366 50078 2020-01-03 06:07:25 544381431 LOCKER RF-T-33 [IN] IN SUBIA, MAY 00:13 13
177967448 50078 2020-01-03 06:07:38 544343461 SENSORS RF-T-19 [IN] IN SUBIA, MAY
177977184 50078 2020-01-03 08:02:59 544352385 SENSORS RF-T-20 [OUT] OUT SUBIA, MAY
177977214 50078 2020-01-03 08:03:21 544381436 LOCKER RF-T-36 [OUT] OUT SUBIA, MAY
177979653 50078 2020-01-03 08:23:54 544381431 LOCKER RF-T-33 [IN] IN SUBIA, MAY 00:20 20
预期输出
先入
USERNAME DATE_TIME First_IN_Time
SUBIA, MAY 2020-01-02 05:45:50 05:45:34
SUBIA, MAY 2020-01-03 05:45:50 06:07:25
最后一个
USERNAME DATE_TIME last_out_Time
SUBIA, MAY 2020-01-02 06:35:51 06:35:51
SUBIA, MAY 2020-01-03 05:45:50 08:02:59
tblshift
SHIFTCODE DATESHIFT STARTSHIFT ENDSHIFT ISRESTDAY
50078 1/24/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 1/25/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 1/26/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 1/27/2020 1/1/1970 2:00:00.000000 PM 1/1/1970 10:00:00.000000 PM 0
50078 2/10/2020 1/1/1970 10:00:00.000000 PM 1/1/1970 6:00:00.000000 AM 0
50078 2/11/2020 1/1/1970 10:00:00.000000 PM 1/1/1970 6:00:00.000000 AM 0
50078 2/12/2020 1/1/1970 10:00:00.000000 PM 1/1/1970 6:00:00.000000 AM
我有什么尝试
Select
max(A.DATE_TIME) keep (dense_rank first order by A.DATE_TIME) first_IN,
--Max(A.DATE_TIME) first_IN,
A.USERNAME
--min (A.DATE_TIME ) first_IN, max (A.DATE_TIME ) last_out,A.USERNAME
--case
--end
from tblaccesslogs a
where A.LOGTYPE = 'IN' and A.READERNAME <> 'LOCKER'
group by A.USERNAME
更新 我需要确定员工是否早退 基于 table tblshift
希望有人能帮我解决这个问题。
您可以使用 aggregate
函数在单个查询中获取上下班时间,如下所示,并将其与理想的班次开始时间进行比较,如下所示:
SELECT
T.USERNAME,
CASE
WHEN FIRST_IN_TIME >
TRUNC(FIRST_IN_TIME) + ( STARTSHIFT - DATE '1970-01-01' ) THEN 'LATE'
ELSE 'ONTIME'
END AS IN_STATUS
FROM
(
SELECT
A.USERNAME,
A.USERID,
TRUNC(A.DATE_TIME) AS DATE_TIME,
MIN(CASE WHEN A.LOGTYPE = 'IN' THEN A.DATE_TIME END) AS FIRST_IN_TIME,
MAX(CASE WHEN A.LOGTYPE = 'OUT' THEN A.DATE_TIME END) AS LAST_OUT_TIME
FROM TBLACCESSLOGS A
WHERE A.READERNAME <> 'LOCKER'
GROUP BY A.USERNAME, A.USERID, TRUNC(A.DATE_TIME)
) T
JOIN TBLSHIFTS S ON T.USERID = S.SHIFTCODE AND TRUNC(T.DATE_TIME) = TRUNC(S.DATESHIFT);
干杯!!
使用ROW_NUMBER
解析函数:
create table tblaccesslogs (
EVENTID,
USERID,
DATE_TIME,
READERID,
READERNAME,
SNAME,
LOGTYPE,
USERNAME
) AS
SELECT 177792329, 50078, DATE '2020-01-02' + INTERVAL '05:45:34' HOUR TO SECOND, 544381431, 'LOCKER', 'RF-T-33', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177792497, 50078, DATE '2020-01-02' + INTERVAL '05:45:50' HOUR TO SECOND, 544343461, 'SENSORS', 'RF-T-19', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177813432, 50078, DATE '2020-01-02' + INTERVAL '06:35:51' HOUR TO SECOND, 544352385, 'SENSORS', 'RF-T-20', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177813495, 50078, DATE '2020-01-02' + INTERVAL '06:36:13' HOUR TO SECOND, 544381436, 'LOCKER', 'RF-T-36', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177950118, 50078, DATE '2020-01-03' + INTERVAL '05:50:48' HOUR TO SECOND, 544352385, 'SENSORS', 'RF-T-20', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177954602, 50078, DATE '2020-01-03' + INTERVAL '05:54:11' HOUR TO SECOND, 544381436, 'LOCKER', 'RF-T-36', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177967366, 50078, DATE '2020-01-03' + INTERVAL '06:07:25' HOUR TO SECOND, 544381431, 'LOCKER', 'RF-T-33', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177967448, 50078, DATE '2020-01-03' + INTERVAL '06:07:38' HOUR TO SECOND, 544343461, 'SENSORS', 'RF-T-19', 'IN', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177977184, 50078, DATE '2020-01-03' + INTERVAL '08:02:59' HOUR TO SECOND, 544352385, 'SENSORS', 'RF-T-20', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177977214, 50078, DATE '2020-01-03' + INTERVAL '08:03:21' HOUR TO SECOND, 544381436, 'LOCKER', 'RF-T-36', 'OUT', 'SUBIA, MAY' FROM DUAL UNION ALL
SELECT 177979653, 50078, DATE '2020-01-03' + INTERVAL '08:23:54' HOUR TO SECOND, 544381431, 'LOCKER', 'RF-T-33', 'IN', 'SUBIA, MAY' FROM DUAL;
然后:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY USERNAME, LOGTYPE, TRUNC( DATE_TIME )
ORDER BY DATE_TIME ASC
) AS first_date_time_rn
FROM tblaccesslogs t
WHERE READERNAME <> 'LOCKER'
)
WHERE logtype = 'IN'
AND first_date_time_rn = 1
输出:
EVENTID | USERID | DATE_TIME | READERID | READERNAME | SNAME | LOGTYPE | USERNAME | FIRST_DATE_TIME_RN --------: | -----: | :------------------ | --------: | :--------- | :------ | :------ | :--------- | -----------------: 177792497 | 50078 | 2020-01-02 05:45:50 | 544343461 | SENSORS | RF-T-19 | IN | SUBIA, MAY | 1 177967448 | 50078 | 2020-01-03 06:07:38 | 544343461 | SENSORS | RF-T-19 | IN | SUBIA, MAY | 1
和:
SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY USERNAME, LOGTYPE, TRUNC( DATE_TIME )
ORDER BY DATE_TIME DESC
) AS last_date_time_rn
FROM tblaccesslogs t
WHERE READERNAME <> 'LOCKER'
)
WHERE logtype = 'OUT'
AND last_date_time_rn = 1
输出:
EVENTID | USERID | DATE_TIME | READERID | READERNAME | SNAME | LOGTYPE | USERNAME | LAST_DATE_TIME_RN --------: | -----: | :------------------ | --------: | :--------- | :------ | :------ | :--------- | ----------------: 177813432 | 50078 | 2020-01-02 06:35:51 | 544352385 | SENSORS | RF-T-20 | OUT | SUBIA, MAY | 1 177977184 | 50078 | 2020-01-03 08:02:59 | 544352385 | SENSORS | RF-T-20 | OUT | SUBIA, MAY | 1
db<>fiddle here