So I've got a set of results that looks something like this:
SELECT User_ID, StartTime, EndTime, TIMEDIFF(EndTime, StartTime) AS TimeDiff
FROM MyTable
------------------------------------------------------------------
| User_ID | StartTime | EndTime | TimeDiff |
------------------------------------------------------------------
| 1 | 2010-11-05 08:00:00 | 2010-11-05 09:00:00 | 01:00:00 |
------------------------------------------------------------------
| 1 | 2010-11-05 09:00:00 | 2010-11-05 10:00:00 | 01:00:00 |
------------------------------------------------------------------
| 2 | 2010-11-05 06:30:00 | 2010-11-05 07:00:00 | 00:30:00 |
------------------------------------------------------------------
| 2 | 2010-11-05 07:00:00 | 2010-11-05 09:00:00 | 02:00:00 |
------------------------------------------------------------------
| 2 | 2010-11-05 09:00:00 | 2010-11-05 10:00:00 | 01:00:00 |
------------------------------------------------------------------
Now I need to group the results by User_ID
and SUM()
TimeDiff. If I add a GROUP BY
clause, it doesn't SUM()
the TimeDiff (and I wouldn't expect it to). How can I SUM()
the TimeDiffs for each User?
SUM() function with group by MySQL SUM() function retrieves the sum value of an expression which has undergone a grouping operation by GROUP BY clause.
MySQL SUM() function retrieves the sum value of an expression which is made up of more than one columns. The above MySQL statement returns the sum of multiplication of 'receive_qty' and 'purch_price' from purchase table for each group of category ('cate_id') .
How Does it Work? The SUM MySQL function does precisely as the name indicates: it returns the sum of a set of values. The SUM function ignores NULL values when encountered in a set. If used in the SELECT clause where no row is returned, the resulting value from the SUM function is a NULL and not a zero.
Use:
SELECT t.user_id,
SEC_TO_TIME(SUM(TIME_TO_SEC(t.endtime) - TIME_TO_SEC(t.starttime))) AS timediff
FROM MYTABLE t
GROUP BY t.user_id
Steps:
Based on the sample data, I'd have just suggested:
SELECT t.user_id,
TIMEDIFF(MIN(t.startdate), MAX(t.enddate)) AS timediff
FROM MYTABLE t
GROUP BY t.user_id
NOTE: There is a bug in this code if you are using datetime. TIME_TO_SEC only converts the time section so you end up with big negatives if the clock goes past midnight. Use UNIX_TIMESTAMP instead to do the sum. Also SEC_TO_TIME maxes out at values greater than 3020399 seconds e.g. SELECT TIME_TO_SEC(SEC_TO_TIME(3020400)); If you see this value 838:59:59 you've reached the max and probably just need to divide by 3600 to just show hours.
AFAIK, your only option is to cast to UNIX_TIMESTAMP
s and do some integer calculations, substituting a random date (I chose 2000-01-01) for TIME columns without a date.
SELECT TIMEDIFF(
DATE_ADD('2000-01-01 00:00:00',
INTERVAL
SUM(UNIX_TIMESTAMP(CONCAT('2000-01-01 ',TimeDiff)) - UNIX_TIMESTAMP('2000-01-01 00:00:00')
SECOND),
'2000-01-01 00:00:00')
FROM MyTable;
Because it may seem you can SUM
TIME columns, but actually they will be cast to nasty integers or floats which will not follow time specifications (try it with a sum of minutes > 60 and you'll see what I mean).
For the ones who claim you can SUM
time columns:
mysql> create table timetest(a TIME);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO timetest VALUES ('02:00'),('03:00');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT SUM(a) FROM timetest;
+--------+
| SUM(a) |
+--------+
| 50000 |
+--------+
1 row in set (0.00 sec)
mysql> SELECT TIME(SUM(a)) FROM timetest;
+--------------+
| TIME(SUM(a)) |
+--------------+
| 05:00:00 |
+--------------+
1 row in set (0.00 sec)
mysql> -- seems ok, but wait
mysql> INSERT INTO timetest VALUES ('02:30');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT TIME(SUM(a)) FROM timetest;
+--------------+
| TIME(SUM(a)) |
+--------------+
| 07:30:00 |
+--------------+
1 row in set (0.00 sec)
mysql> -- and now, oh ye unbelievers:
mysql> INSERT INTO timetest VALUES ('01:40');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT TIME(SUM(a)) FROM timetest;
+--------------+
| TIME(SUM(a)) |
+--------------+
| NULL |
+--------------+
1 row in set, 1 warning (0.00 sec)
mysql> -- why is that? because it uses integer arithmetic, not time - arithmetic:
mysql> SELECT SUM(a) FROM timetest;
+--------+
| SUM(a) |
+--------+
| 87000 |
+--------+
1 row in set (0.00 sec)
mysql> -- that cannot be cast to time
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With