计算MySQL查询期间的时差

时间:2014-12-17 10:07:05

标签: php mysql datetime

我有两个MySQL表,都包含DATETIME字段:

  1. 表格beginnings包含某个流程设置的时间
  2. events包含某些事件由该过程引起的时间
  3. 开始是在晚上;事件发生在第二天早上。请注意,每个开头后面都会有不断变化的多个事件!

    以下是两个示例表:

    CREATE TABLE IF NOT EXISTS `beginnings` (
      `bid` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `begin` datetime NOT NULL,
      PRIMARY KEY (`bid`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
    
    INSERT INTO `beginnings` (`bid`, `begin`) VALUES
    (1, '2014-09-24 22:44:00'),
    (2, '2014-09-25 21:32:00'),
    (3, '2014-09-28 22:01:00');
    
    CREATE TABLE IF NOT EXISTS `events` (
      `eid` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `event` datetime NOT NULL,
      PRIMARY KEY (`eid`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
    
    INSERT INTO `events` (`eid`, `event`) VALUES
    (1, '2014-09-25 02:07:00'),
    (2, '2014-09-25 04:06:00'),
    (3, '2014-09-25 05:50:00'),
    (4, '2014-09-26 02:07:00'),
    (5, '2014-09-26 04:15:00'),
    (7, '2014-09-29 01:08:00'),
    (8, '2014-09-29 04:21:00'),
    (6, '2014-09-29 05:02:00'),
    (9, '2014-09-29 05:25:00');
    

    我想计算每个事件与各自开始之间的时差(以分钟为单位)。

    目前,我正在从数据库中提取数据,将日期时间条目转换为时间戳,并计算PHP中的差异。这是一个带有编号的简化示例代码,以便于阅读:

    $events = range(1, 50);
    $beginnings = array(7, 11, 19, 27, 29, 36, 40, 43);
    $events = array_merge(array_diff($events, $beginnings));
    
    $differences = array();
    for($i = 0; $i < count($beginnings); $i++) {
        foreach($events as $event) {
            if($event > $beginnings[$i] && $event < $beginnings[$i + 1]) {
                $differences[] = $event - $beginnings[$i];
            }
        }
    }
    

    我的问题:

    在查询期间是否可以在MySQL中计算这些差异?


    说明性示例:

    你是一家汽车厂的老板。每天晚上,在你入睡之前,你会告诉夜班的车队每辆车都要制造一辆车并注意他们什么时候完成它。当你早上回来时,你想要计算不同的团队建造他们各自的汽车需要多长时间。你看到一支车队在两小时内完成了他们的车,而另一支车队需要五个小时才能完成他们的车。你很好奇,所以你要注意一年的时间,然后做一些统计。

2 个答案:

答案 0 :(得分:0)

您可以使用datedifftimediff

功能
SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
    -> -31

http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_datediff

SELECT TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002');
    -> '46:58:57.999999'

http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timediff

<小时/> 您还可以将两个DateTime值转换为整数(自Unix纪元以来的秒数)并将它们减去正常数字。

SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19');
    -> 1196440219

http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_unix-timestamp


回复以下评论的样本。但是,您应该阅读SELECT,JOIN和WHERE语句。这是简单的MySQL,应该在使用更复杂的函数之前理解它。 见http://dev.mysql.com/doc/refman/5.7/en/select.html

SELECT TIMEDIFF(events.event, beginnings.begin)
FROM event
INNER JOIN beginnings ON beginnings.eid = events.eid

注意此选择将根据您的表结构无效,因为起始表缺少事件的关系ID。我在这里使用了eid。在使用该选择并相应地调整之前,您需要了解这两个表如何相互关联。我不能在这里唠叨你,因为我可以看到你的表格与你有什么关系。您的旧代码在PHP中进行了硬编码的关系,这意味着您无法在MySQL中进行选择。

答案 1 :(得分:0)

好吧,如果是我,我可能会做这样的事情......

DROP TABLE project_events;

CREATE TABLE project_events
(project_id INT NOT NULL
,event_date DATETIME NOT NULL
);

INSERT INTO project_events VALUES
(1, '2014-09-24 22:44:00'),
(1, '2014-09-25 02:07:00'),
(1, '2014-09-25 04:06:00'),
(1, '2014-09-25 05:50:00'),

(2, '2014-09-25 21:32:00'),
(2, '2014-09-26 02:07:00'),
(2, '2014-09-26 04:15:00'),

(3, '2014-09-28 22:01:00'),
(3, '2014-09-29 01:08:00'),
(3, '2014-09-29 04:21:00'),
(3, '2014-09-29 05:02:00'),
(3, '2014-09-29 05:25:00');

SELECT project_id
     , MIN(event_date) start
     , MAX(event_date) end
     , TIMEDIFF(MAX(event_date)
     , MIN(event_date)) duration 
  FROM project_events 
 GROUP 
    BY project_id;
+------------+---------------------+---------------------+----------+
| project_id | start               | end                 | duration |
+------------+---------------------+---------------------+----------+
|          1 | 2014-09-24 22:44:00 | 2014-09-25 05:50:00 | 07:06:00 |
|          2 | 2014-09-25 21:32:00 | 2014-09-26 04:15:00 | 06:43:00 |
|          3 | 2014-09-28 22:01:00 | 2014-09-29 05:25:00 | 07:24:00 |
+------------+---------------------+---------------------+----------+

此架构允许项目超载或重叠的可能性。您可能有充分的理由希望将“起点”存储在单独的表中 - 但是考虑到这一点,调整此解决方案将是微不足道的。它只涉及到project_id的连接。

编辑:这是将开始日期与该项目的所有后续日期进行比较的一种方法:

SELECT x.project_id
     , MIN(y.event_date) start
     , x.event_date end
     , TIMEDIFF(x.event_date,MIN(y.event_date)) duration 
  FROM project_events x 
  JOIN project_events y 
    ON y.project_id = x.project_id 
 GROUP 
    BY x.project_id,x.event_date;
+------------+---------------------+---------------------+----------+
| project_id | start               | end                 | duration |
+------------+---------------------+---------------------+----------+
|          1 | 2014-09-24 22:44:00 | 2014-09-24 22:44:00 | 00:00:00 |
|          1 | 2014-09-24 22:44:00 | 2014-09-25 02:07:00 | 03:23:00 |
|          1 | 2014-09-24 22:44:00 | 2014-09-25 04:06:00 | 05:22:00 |
|          1 | 2014-09-24 22:44:00 | 2014-09-25 05:50:00 | 07:06:00 |
|          2 | 2014-09-25 21:32:00 | 2014-09-25 21:32:00 | 00:00:00 |
|          2 | 2014-09-25 21:32:00 | 2014-09-26 02:07:00 | 04:35:00 |
|          2 | 2014-09-25 21:32:00 | 2014-09-26 04:15:00 | 06:43:00 |
|          3 | 2014-09-28 22:01:00 | 2014-09-28 22:01:00 | 00:00:00 |
|          3 | 2014-09-28 22:01:00 | 2014-09-29 01:08:00 | 03:07:00 |
|          3 | 2014-09-28 22:01:00 | 2014-09-29 04:21:00 | 06:20:00 |
|          3 | 2014-09-28 22:01:00 | 2014-09-29 05:02:00 | 07:01:00 |
|          3 | 2014-09-28 22:01:00 | 2014-09-29 05:25:00 | 07:24:00 |
+------------+---------------------+---------------------+----------+
相关问题