我有两个 MySQL 表,都包含 DATETIME 字段:
- 表
beginnings
包含某个进程启动的时间 - 表
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/