Reputation: 242
Hi i'm trying to write a query that will give me output of
users first IN and last out each day where reader name is not Locker and identify whether he is late IN or early OUT
sample data:
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
expected output
first IN
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
last out
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
what i have try
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
Update i need to identify whether employee is late in our early out base on the table tblshift
Hope some one help me out with this.
Upvotes: 0
Views: 76
Reputation: 167981
Use the ROW_NUMBER
analytic function:
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;
Then:
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
outputs:
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
and:
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
outputs:
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
Upvotes: 0
Reputation: 35910
You can use an aggregate
function to fetch the in and out time in a single query as following and compare it with ideal shift start time as following:
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);
Cheers!!
Upvotes: 1