我有一个事件表,每个事件表在MySQL表中都有一个StartTime和EndTime(作为DateTime类型)。
我正在尝试输出重叠时间和重叠事件的总数。
在MySQL中执行此查询的最有效/最简单的方法是什么?
CREATE TABLE IF NOT EXISTS `events` (
`EventID` int(10) unsigned NOT NULL auto_increment,
`StartTime` datetime NOT NULL,
`EndTime` datetime default NULL,
PRIMARY KEY (`EventID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=37 ;
INSERT INTO `events` (`EventID`, `StartTime`, `EndTime`) VALUES
(10001, '2009-02-09 03:00:00', '2009-02-09 10:00:00'),
(10002, '2009-02-09 05:00:00', '2009-02-09 09:00:00'),
(10003, '2009-02-09 07:00:00', '2009-02-09 09:00:00');
# if the query was run using the data above,
# the table below would be the desired output
# Number of Overlapped Events | Total Amount of Time those events overlapped.
1, 03:00:00
2, 02:00:00
3, 02:00:00
Run Code Online (Sandbox Code Playgroud)
这些结果的目的是生成使用小时数的账单。(如果您正在运行一个事件,那么您可能每小时需要支付10美元。但是,如果正在运行两个事件,则您每小时只需要支付8美元,但是在运行两个事件的时间段内。)
尝试这个:
SELECT `COUNT`, SEC_TO_TIME(SUM(Duration))
FROM (
SELECT
COUNT(*) AS `Count`,
UNIX_TIMESTAMP(Times2.Time) - UNIX_TIMESTAMP(Times1.Time) AS Duration
FROM (
SELECT @rownum1 := @rownum1 + 1 AS rownum, `Time`
FROM (
SELECT DISTINCT(StartTime) AS `Time` FROM events
UNION
SELECT DISTINCT(EndTime) AS `Time` FROM events
) AS AllTimes, (SELECT @rownum1 := 0) AS Rownum
ORDER BY `Time` DESC
) As Times1
JOIN (
SELECT @rownum2 := @rownum2 + 1 AS rownum, `Time`
FROM (
SELECT DISTINCT(StartTime) AS `Time` FROM events
UNION
SELECT DISTINCT(EndTime) AS `Time` FROM events
) AS AllTimes, (SELECT @rownum2 := 0) AS Rownum
ORDER BY `Time` DESC
) As Times2
ON Times1.rownum = Times2.rownum + 1
JOIN events ON Times1.Time >= events.StartTime AND Times2.Time <= events.EndTime
GROUP BY Times1.rownum
) Totals
GROUP BY `Count`
Run Code Online (Sandbox Code Playgroud)
结果:
1, 03:00:00
2, 02:00:00
3, 02:00:00
Run Code Online (Sandbox Code Playgroud)
如果这样做不能满足您的要求,或者您需要一些解释,请告诉我。通过将重复的子查询存储AllTimes在临时表中可以使其速度更快,但是希望它可以足够快地运行。
| 归档时间: |
|
| 查看次数: |
2905 次 |
| 最近记录: |