sql >> Database teknologi >  >> RDS >> Mysql

Tidsforskel mellem swipe-in ​​og swipe-out for medarbejdere; tillade bagklap og udgang på en anden dag

Med hjælp fra en ven løste jeg problemet nævnt i Punkt #2 :ved nedenstående trin ,Da jeg kun ville have løsningen i sql-script , med min lille sql-viden designede jeg løsningen i 3 trin, jeg er sikker på, at den kan håndteres på en enklere måde af eksperter :

I betragtning af basistabel som EMP_DATA brugte jeg én midlertidig tabel:Temp_1For basistabel har jeg tilføjet et "VALIDITY"-felt for at markere posterne ved det sidste trin.

EMP_DATA:

EMPID EVENT_TYPE Swipe_time       VALIDITY
1     EN1        2012-06-01 12:00
1     EX         2012-06-01 12:30
2     EN1        2012-06-01 12:50
1     EN2        2012-06-01 13:10
1     EN2        2012-06-01 15:50
2     EX         2012-06-01 13:30
2     EN1        2012-06-01 14:00
2     EX         2012-06-02 19:00
1     EX         2012-06-02 19:30

Trin 1:

nedenstående forespørgsel vil tildele rækkenumrene for rækker i EMP_DATA og kopiere dem til temp_1 tabel:

create table Temp_1 (EMP_ID int, Event_Type char(10), Swipe_Time datetime, rownum int, Lastevent char(10), Nextevent char(10)) 

Insert into  Temp_1             
SELECT  EMP_ID, EVENT_TYPE,
ROW_NUMBER() OVER ( PARTITION BY EMP_ID 
ORDER BY SWIPE_TIME ) AS RowNumber      
    FROM EMP_DATA

Trin 1 Output:

 EMPID EVENT_TYPE Swipe_time         RowNumber  LastEvent  NextEvent
1     EN1        2012-06-01 12:00    1
1     EX         2012-06-01 12:30    2
2     EN1        2012-06-01 12:50    1
1     EN2        2012-06-01 13:10    3
1     EN2        2012-06-01 15:50    4
2     EX         2012-06-01 13:30    2
2     EN1        2012-06-01 14:00    3
2     EX         2012-06-02 19:00    4
1     EX         2012-06-02 19:30    5

Trin 2:

identificer sidste hændelse (forrige hændelse ) og næste hændelse for hver hændelse i rækken i tabellen temp_1

 Update  main set main.LastEvent =yy.LEvent,main.NextEvent=yy.NEvent
 from TEMP_1 main
 inner join
 ( SELECT   A.EMP_ID , A.EVENT_TYPE, A.SWIPE_TIME, A.ROWNUMBER                                                                                                                                                                                                                                                          
               COALESCE(LastVal.ZONE_NAME, 'N/A') AS LEvent ,                                                                                                                                                                                                                                                               
                   COALESCE(NextVal1.ZONE_NAME, 'N/A') AS NEvent                                                                                                                                                                                                                                                       
          FROM Temp_1  A                                                                                                                                                                                                                                                               
               LEFT JOIN Temp_1 LastVal                                                                                                                                                                                                                                                        
                  ON A.EMP_ID= LastVal.EMP_ID
                     AND A.ROWNUMBER - 1 = LastVal.ROWNUMBER                                                                                                                                                                                                                                                   
               LEFT JOIN Temp_1 NextVal1                                                                                                                                                                                                                                                    
                  ON A.EMP_ID= NextVal1.EMP_ID
                     AND A.ROWNUMBER + 1 = NextVal1.ROWNUMBER)yy                                       
on main.EMP_ID=yy.EMP_ID,
and main.event_type=yy.event_type
and main.swipe_time = yy.swipe_event

Trin 2 Output:

EMPID EVENT_TYPE Swipe_time         RowNumber  LastEvent  NextEvent
1     EN1        2012-06-01 12:00    1           N/A        EX
1     EX         2012-06-01 12:30    2           EN1        EN2
2     EN1        2012-06-01 12:50    1           N/A        EX
1     EN2        2012-06-01 13:10    3           EX         EN2
1     EN2        2012-06-01 15:50    4           EN2        EX
2     EX         2012-06-01 13:30    2           EN1        EN1
2     EN1        2012-06-01 14:00    3           EX         EX
2     EX         2012-06-02 19:00    4           EN1        N/A
1     EX         2012-06-02 19:30    5           EN2        N/A

Trin 3:

Baseret på LastEvent og NextEvent kan vi identificere de bagerste poster og opdatere hovedtabellen EMP_DATA ved hjælp af nedenstående forespørgsel:

 Update emp set emp.VALIDITY='N'
from EMP_DATA
INNER JOIN
(select *
from TEMP_1
where (EVENT_TYPE = 'EX' and LastEvent = 'EX') 
or (EVENT_TYPE IN ('EN1','EN2') and NextEvent  IN ('EN1','EN2')))yy
ON emp.EMP_ID = yy.EMP_ID
and emp.EVENT_TYPE = yy.EMP_ID
and emp.Swipe_time = yy.Swipe_time

Endelig output: *Trin 3 Output: *

EMPID EVENT_TYPE Swipe_time       VALIDITY
1     EN1        2012-06-01 12:00
1     EX         2012-06-01 12:30
2     EN1        2012-06-01 12:50
1     EN2        2012-06-01 13:10    N
1     EN2        2012-06-01 15:50    
2     EX         2012-06-01 13:30
2     EN1        2012-06-01 14:00
2     EX         2012-06-02 19:00
1     EX         2012-06-02 19:30



  1. Tjek om dette er duplikat

  2. ORA-01795:maksimalt antal udtryk på en liste er 1000, hvordan opdeles strengen

  3. Vælg, at alle data inkluderer en anden tabel, selvom den er null

  4. OPDATERING med CASE og IN - Oracle