php - 计算MySQL查询时的时间差

标签 php mysql datetime

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

  1. beginnings 包含某个进程启动的时间
  2. events 包含特定事件由该进程引起的时间

开始是在晚上;事件发生在第二天早上。请注意,每个开始后都会发生数量不断变化的多个事件!

这里有两个示例表:

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中计算出这些差异?


示例:

你是一家汽车厂的老板。每天晚上,在你 sleep 之前,你告诉夜类的团队每人制造一辆汽车,并记下他们何时完成。当你早上回来时,你想计算不同的团队花了多长时间来制造他们各自的汽车。您会看到一个团队在两个小时内完成了他们的汽车,而另一个团队需要五个小时才能完成他们的汽车。你很好奇,所以你一直记录一年的时间,然后做一些统计。

最佳答案

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

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 |
+------------+---------------------+---------------------+----------+

关于php - 计算MySQL查询时的时间差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27523019/

相关文章:

java - 给定两个不包括周末的日期计算日期

mysql - 编译语句时出错: FAILED: SemanticException [Error 10002]

mysql - 更改 mysql 中的事件调度程序状态

r - 从 DocumentDB 导入到 Azure 机器学习 - 以毫秒为单位的日期时间

php - 使用多个嵌套循环的最佳方式

mysql - Spring Data JPA 中的内连接查询和基于接口(interface)的投影

sql - Informix 7.3 - 声明日期列数据类型,默认为插入/更新时的当前日期

php - laravel 中针对特定格式的 TIme 格式验证

php - 想知道 Laravel 的类(class)持续时间还剩多少天

php - 从脚本中获取访问者数量