Home > Software engineering >  MySQL Script for update another table with some calculation after updating the existing table
MySQL Script for update another table with some calculation after updating the existing table

Time:10-30

I have written one MySQL Query which is finding missing attendance from clockInTest table and then inserted a new row for the end time of that day. But, I also need to calculate the total office hours and break time of that days (which are newly inserted), and that I have to update the WorkDay table with timeSpan and breakTime. Following are the sample data I am using:

Before executing my Query:

Id TimeStamp WorkDayId EmployeeId Type
1 2021-10-26 08:00:00 149 1 Start
2 2021-10-25 08:00:00 148 1 Start
3 2021-10-26 10:00:00 149 1 End
4 2021-10-26 12:00:00 149 1 Start

After executing the following Query:

START TRANSACTION;
INSERT INTO ClockInTest (PartnerId, Timestamp, WorkDayId, UserId, EmployeeId, Type )
SELECT a.PartnerId, CONCAT(DATE(a.TimeStamp),' 23:59:00'), a.WorkDayId, a.UserId, a.EmployeeId, 'End'
FROM  ClockInTest a
WHERE a.Type = 'Start' 
AND a.DeletedAt IS NULL
AND a.TIMESTAMP <= NOW() - INTERVAL 1 DAY
AND NOT EXISTS (
  SELECT 1
  FROM  ClockInTest b
  WHERE b.EmployeeId = a.EmployeeId
  AND a.WorkDayId = b.WorkDayId
  AND a.Timestamp < b.Timestamp
  AND b.Type = 'End'
  AND b.DeletedAt IS NULL
) GROUP BY a.WorkDayId, a.EmployeeId;
SELECT * FROM clockintest WHERE WorkDayId IN (
SELECT DISTINCT c.WorkDayId FROM clockintest c WHERE c.Id >= LAST_INSERT_ID());
COMMIT;

clockInTest table after the query execution:

Id TimeStamp WorkDayId EmployeeId Type
1 2021-10-26 08:00:00 149 1 Start
2 2021-10-25 08:00:00 148 1 Start
3 2021-10-26 10:00:00 149 1 End
4 2021-10-26 12:00:00 149 1 Start
5 2021-10-26 23:59:00 149 1 End
6 2021-10-25 23:59:00 148 1 End

So, the above table missing data are added. Now, I have to calculate the total working hours (timeSpan) and break time for each WorkDayId and after that, I have to update the WorkDay table which is like following:

WorkDay table

Id TimeSpan EmployeeId BreakTime
148 1
149 1

Expected Result in WorkDay Table:

Id TimeSpan EmployeeId BreakTime
148 57540000 1 0
149 50,328,000 1 7200000

** TimeSpan and BreakTime in miliseconds

CodePudding user response:

I guess we can combine tables data for each Start type, and find the respective End time and the Next Start time if any

   WorkDayId | EmployeeId | Start | End | Next Start
    148 | 1 | 2021-10-25 08:00:00 | 2021-10-25 23:59:00 
    149 | 1 | 2021-10-26 08:00:00 | 2021-10-26 10:00:00 | 2021-10-26 12:00:00
    149 | 1 | 2021-10-26 12:00:00 | 2021-10-26 23:59:00 | 

Then the expected result is simply sum up of the time diff

SELECT 
  a.WorkDayId, 
  a.EmployeeId, 
  SUM(TIMESTAMPDIFF(SECOND, a.`TimeStamp`, b.`TimeStamp`)) * 1000 AS timespan,
  SUM(CASE WHEN c.`Timestamp` IS NULL THEN 0 ELSE TIMESTAMPDIFF(SECOND, b.`TimeStamp`, c.`TimeStamp`) END) * 1000 AS breakTime
FROM clockInTest a 
JOIN clockInTest b 
  ON a.EmployeeId = b.EmployeeId 
     AND a.WorkDayId = b.WorkDayId 
     AND b.`Timestamp` > a.`Timestamp`
LEFT JOIN clockInTest c 
  ON a.EmployeeId = c.EmployeeId 
     AND a.WorkDayId = c.WorkDayId 
     AND c.`Type` = 'Start' 
     AND c.`Timestamp` > b.`Timestamp` 
WHERE a.`Type` = 'Start'
AND b.`Type` = 'End'
AND NOT EXISTS (
  SELECT 1
  FROM clockInTest d
  WHERE a.EmployeeId = d.EmployeeId
  AND a.WorkDayId = d.WorkDayId
  AND (
        ( d.`Timestamp` > a.`Timestamp` AND d.`Timestamp` < b.`Timestamp` )
     OR ( d.`Timestamp` > b.`Timestamp` AND d.`Timestamp` < c.`Timestamp` )
  ) 
)
GROUP BY a.WorkDayId, a.EmployeeId
ORDER BY a.WorkDayId, a.EmployeeId

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=eb3b1fef815f1201554fdca683a8448f

To update the results to WorkDay table, assume the WorkDayId & EmployeeId records exist and timespan & breakTime are empty

UPDATE WorkDay w
JOIN (
  ... // the above select query
) g ON w.id = g.WorkDayId AND w.EmployeeId = g.EmployeeId
SET w.TimeSpan = g.timespan, w.BreakTime = g.breakTime
;

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=2262e5156c0a991eddbbb39ebacfd3bf

  • Related