Skip to content
Advertisement

Postgres – calculate total working hours based on IN and OUT entry

I have the below tables:

1) My Company table


2) My User table


3) My Attendance table


I need to calculate the attendance grouped by date, u_id like below:
Note: The query parameters would be the “From Date”, “To Date” and “Company ID”


Is this possible in PostgreSQL?

Advertisement

Answer

The tricky part is to expand one row that covers two (calendar) days to two rows and allocating the hours of the “next” day correctly.

The first part is to get a pivot table that combines IN/OUT pairs into a single row.

A simple (yet not very efficient) approach is:

The next step is to break up the rows with more than one day into two rows.

This assumes that you never have an IN/OUT pair that covers more than two days!

The above returns the following for your sample data:

How does this work?

So we first select all those rows that start and end on the same day with this part:

The second part of the union splits up the rows that span two days by using a cross join that generates one row with the original start time and midnight, and another from midnight to the original end time:

At the end the new “expanded” rows are then aggregated by grouping them by user and date and left joined to the users table to get the username as well.

Which then results in:

The “duration” column is an interval which you can format to your liking.

Online example

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement