Marcus Olsson
Marcus Olsson

Reputation: 2527

Using SUM() per a row basis in MySQL

I'm building a very simple application where I can "clock in" on various tasks, and for this I've got a database table in MySQL that looks like something like this:

|ID|user_id |task_id|checkin_time       |checkout_time
------------------------------------------------------------
|31|2       |289    |2012-07-12 09:50:03|2012-07-12 09:51:27
|32|2       |289    |2012-07-12 10:00:05|2012-07-12 13:00:05

What I want to get out of this, with a SQL-query, is total time checked in per day by a user for the last week. I tried this query:

SELECT COUNT( id ) AS time_id, SUM( checkout_time - checkin_time ) AS total_time, DATE( checkout_time ) AS checkout_day
FROM time_table
WHERE user_id =  '2'
AND checkout_time >= ( DATE_SUB( CURDATE( ) , INTERVAL 1 WEEK ) ) 
GROUP BY checkout_day
ORDER BY checkout_day ASC

Which gives a very nice result, but there are some serious complications if there are more than one "checkin" a day – as SUM( checkout_time - checkin_time ) takes the first checkin_time, and last checkout_time – which doesn't necessarily represent how much time a user have been checked in (unless he have been checked in 100% of the time).

What I want is for SUM() to take each sum, and then add them up for a day to day basis.

Any ideas on how I fix this?

Upvotes: 3

Views: 1003

Answers (2)

Fredy
Fredy

Reputation: 2910

Try this:

difference in "Days" :

SELECT COUNT( id ) AS time_id, SUM( TO_DAYS(checkout_time) - TO_DAYS(checkin_time) ) AS total_time, DATE( checkout_time ) AS checkout_day
FROM time_table
WHERE user_id =  '2'
AND checkout_time >= ( DATE_SUB( CURDATE( ) , INTERVAL 1 WEEK ) ) 
GROUP BY checkout_day
ORDER BY checkout_day ASC

difference in "Seconds" :

SELECT COUNT( id ) AS time_id, SUM( UNIX_TIMESTAMP(checkout_time) - UNIX_TIMESTAMP(checkin_time) ) AS total_time, DATE( checkout_time ) AS checkout_day
    FROM time_table
    WHERE user_id =  '2'
    AND checkout_time >= ( DATE_SUB( CURDATE( ) , INTERVAL 1 WEEK ) ) 
    GROUP BY checkout_day
    ORDER BY checkout_day ASC

Upvotes: 1

Frank Schmitt
Frank Schmitt

Reputation: 30845

Use a subquery to get the time difference, and sum afterwards:

SELECT 
  COUNT( id ) AS time_id, 
  SUM( time_diff ) AS total_time, 
  DATE( checkout_time ) AS checkout_day
FROM (
  select 
    id, 
    checkout_time - checkin_time as time_diff, 
    checkout_time
  from time_table)
WHERE user_id =  '2'
AND checkout_time >= ( DATE_SUB( CURDATE( ) , INTERVAL 1 WEEK ) ) 
GROUP BY checkout_day
ORDER BY checkout_day ASC

Upvotes: 2

Related Questions