从孩子那里得到时差

时间:2015-05-07 14:12:18

标签: mysql sql date laravel eloquent

我有以下结构

----------
presences
----------
id
started
ended
user_id

---------
breaks
---------
id
presence_id
started
ended

我需要创建一个SQL查询,它返回以下信息

presence_id user_id presence_time breaks_time

其中存在时间是(presence.ended - 存在 - 开始) - 与存在相关的所有休息的(break.ended - break.started)的总和

是否有一种通过SQL查询获取此信息的有效方法?

如果你知道如何以雄辩的方式做到这一点,那就更好了:D

非常感谢你!

3 个答案:

答案 0 :(得分:2)

http://sqlfiddle.com/#!9/650a2/3

SELECT p.id presence_id,
    p.user_id,
    (p.ended-p.started) presence_time , 
    SUM(b.ended-b.started) breaks_time
FROM presences p
LEFT JOIN breaks b
ON p.id = b.presence_id
GROUP BY p.id

更新按user_id分组的相同查询:

http://sqlfiddle.com/#!9/1ce21/1

SELECT 
    sub_total.user_id,
    SUM(sub_total.presence_time) , 
    SUM(sub_total.breaks_time)
FROM (
SELECT p.id presence_id,
    p.user_id,
    (p.ended-p.started) presence_time , 
    SUM(b.ended-b.started) breaks_time
FROM presences p
LEFT JOIN breaks b
ON p.id = b.presence_id
GROUP BY p.id) sub_total
GROUP BY sub_total.user_id

答案 1 :(得分:1)

如果您的startedended存储为datetimetimestamp,那么您可以轻松地进行计算并在几分钟内找到数据。 当有人在工作时间内进行多次短暂休息时,以下示例将非常有用。

稍后在应用程序级别中,您可以将分钟转换为小时。以下是如何在mysql中执行的操作

mysql> select * from presence ;
+------+---------------------+---------------------+---------+
| id   | started             | ended               | user_id |
+------+---------------------+---------------------+---------+
|    1 | 2015-01-01 09:00:00 | 2015-01-01 18:00:00 |      10 |
|    2 | 2015-01-01 09:20:00 | 2015-01-01 18:04:00 |      11 |
|    3 | 2015-01-01 09:10:00 | 2015-01-01 18:30:00 |      12 |
|    4 | 2015-01-02 09:23:10 | 2015-01-02 18:10:00 |      10 |
|    5 | 2015-01-02 09:50:00 | 2015-01-02 19:00:00 |      11 |
|    6 | 2015-01-02 09:10:00 | 2015-01-02 18:36:30 |      12 |
+------+---------------------+---------------------+---------+
6 rows in set (0.00 sec)

mysql> select * from breaks ;
+------+-------------+---------------------+---------------------+
| id   | presence_id | started             | ended               |
+------+-------------+---------------------+---------------------+
|    1 |           1 | 2015-01-01 12:00:00 | 2015-01-01 12:20:30 |
|    2 |           1 | 2015-01-01 15:46:30 | 2015-01-01 15:54:26 |
|    3 |           2 | 2015-01-01 11:26:30 | 2015-01-01 11:34:23 |
|    4 |           2 | 2015-01-01 14:06:45 | 2015-01-01 14:10:20 |
|    5 |           2 | 2015-01-01 16:01:10 | 2015-01-01 16:14:57 |
|    6 |           3 | 2015-01-01 12:11:20 | 2015-01-01 12:40:05 |
|    7 |           3 | 2015-01-01 17:01:10 | 2015-01-01 17:24:21 |
|    8 |           4 | 2015-01-02 12:50:00 | 2015-01-02 13:40:00 |
|    9 |           5 | 2015-01-02 12:20:00 | 2015-01-02 13:05:30 |
|   10 |           5 | 2015-01-02 17:03:00 | 2015-01-02 17:20:00 |
|   11 |           6 | 2015-01-02 12:16:50 | 2015-01-02 12:58:30 |
+------+-------------+---------------------+---------------------+
11 rows in set (0.00 sec)



select
p.id as presence_id,
p.user_id,
timestampdiff(minute,started,ended) - b.break_time as presence_time,
b.break_time from presence p
left join (
 select
 presence_id,
 coalesce(sum( timestampdiff(minute,started,ended ) ),0) as break_time
 from breaks
 group by presence_id
)b
on b.presence_id = p.id

+-------------+---------+---------------+------------+
| presence_id | user_id | presence_time | break_time |
+-------------+---------+---------------+------------+
|           1 |      10 |           513 |         27 |
|           2 |      11 |           501 |         23 |
|           3 |      12 |           509 |         51 |
|           4 |      10 |           476 |         50 |
|           5 |      11 |           488 |         62 |
|           6 |      12 |           525 |         41 |
+-------------+---------+---------------+------------+
6 rows in set (0.00 sec)

答案 2 :(得分:0)

感谢@Alex我得到了它,我的最终查询是以下(使用时间戳)

SELECT *,
        TIME_TO_SEC(TIMEDIFF(p.ended,p.started)) as presence_time,
    sum(TIME_TO_SEC(TIMEDIFF(b.ended,b.started))) as breaks_time

FROM presences p
left join presences_breaks b on b.presence_id = p.id
group by p.id