【问题标题】:get time difference from childs从孩子那里获得时差
【发布时间】:2015-07-18 04:17:44
【问题描述】:

我有以下结构

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

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

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

presence_id user_id presence_time breaks_time

出席时间是 (presence.ended - present-started) - 与出席相关的所有中断的 (break.ended - break.started) 总和

有没有一种通过 sql 查询获取这些信息的有效方法?

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

非常感谢!

【问题讨论】:

  • 您的开始和结束是时间戳还是日期时间?
  • 它们是时间戳

标签: mysql sql date laravel eloquent


【解决方案1】:

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

【讨论】:

  • 为什么?如果 mysql 可以在这两个字段之间执行减号 - 操作,它就可以工作。由于它没有在 OP 中设置,因此我将其设置为 int,但您可以尝试任何您想要的。查询不会有太大变化,只是类型转换。
  • 非常感谢!它有效,检查我自己的答案以查看带有时间戳的最终查询
【解决方案2】:

感谢@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

【讨论】:

  • 由于您没有提供小提琴,我不确定您的查询是否有效:-) sum(TIME_TO_SEC(TIMEDIFF(p.ended,p.started))) as presence_time, 是错误的。如果您将使用任何有 2 次或更多中断的数据集对其进行测试 - 您会看到存在时间将乘以您拥有的中断次数。所以一定是TIME_TO_SEC(TIMEDIFF(p.ended,p.started)) as presence_time,
  • 你是对的! Presence_time 的总和成倍增长!
  • 如果我现在想按 user_id 分组呢?
【解决方案3】:

如果您的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)

【讨论】:

    猜你喜欢
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2014-11-18
    相关资源
    最近更新 更多