我有一个包含设备启动/停止时间和设备标识符的表。我最终想要实现的结果是在指定范围内的每一天的给定时间段(以秒为单位)内对每日运行时间和运行时间进行分组。
我想要实现的目标:
time ADduration PPduration
2014-07-18 0.66 0.66
2014-07-20 0.53 0.30
数据库的一部分:
CREATE TABLE ac
(
startTime datetime,
endTime datetime,
status tinyint(4),
device varchar(5)
);
INSERT INTO ac
(startTime, endTime, status, device)
VALUES
('2014-07-18 05:00:00','2014-07-18 05:04:00',1,'PWR6'),
('2014-07-18 05:54:00','2014-07-18 06:06:00',1,'PWR8'),
('2014-07-18 06:57:00','2014-07-18 07:11:00',1,'PWR8'),
('2014-07-18 10:01:00','2014-07-18 10:15:00',1,'PWR8'),
('2014-07-20 22:37:00','2014-07-20 22:55:00',1,'PWR8'),
('2014-07-20 22:38:00','2014-07-20 22:40:00',1,'PWR6'),
('2014-07-20 23:07:00','2014-07-20 23:12:00',1,'PWR6'),
('2014-07-20 23:12:00','2014-07-20 23:26:00',1,'PWR8'),
('2014-07-20 23:39:00','2014-07-20 23:44:00',1,'PWR6');
我已经阅读了'日历表'技巧,所以我的数据库中也有一个日历表。
CREATE TABLE calendar (calendar_date date);
INSERT INTO calendar (calendar_date)
VALUES
('2014-07-18'),
('2014-07-19'),
('2014-07-20');
我已经构建了几个几乎实现我正在寻找的查询,但我似乎无法将它们全部包装在一起。
此查询可以获取与我的数据表连接的日历,以确保我的结果中仍然显示没有任何数据的日期,但我认为我需要一个子选择,以确保只包含一个设备。
SELECT calendar.calendar_date as DATE, IFNULL(truncate(sum(TIMESTAMPDIFF(second, startTime, stopTime))/60/60,2),0) AS duration
FROM `ac` RIGHT JOIN calendar ON (DATE(startTime) = calendar.calendar_date)
WHERE calendar.calendar_date BETWEEN '2014-07-18' AND '2014-07-20'
GROUP BY DATE
结果:
DATE, duration
2014-07-18, 0.73
2014-07-19, 0.00
2014-07-20, 0.73
这与我来的一样接近,但它并不包括指定范围内的所有日期,并且当第二个选择中的时间选择器将结果限制为0行时,选择范围越大未能包含给定数据的日期。
SELECT AllDay.time, AllDay.duration as ADduration, PP.duration as PPduration
FROM (
SELECT date(startTime) as time, truncate(sum(TIMESTAMPDIFF(second, startTime, stopTime))/60/60,2) as duration
FROM `ac`
WHERE startTime BETWEEN '2014-07-18' AND '2014-07-22'
AND device = 'PWR8'
GROUP BY date(startTime)) AllDay
INNER JOIN (
SELECT date(startTime) as time, truncate(sum(TIMESTAMPDIFF(second, startTime, stopTime))/60/60,2) as duration
FROM `ac`
WHERE startTime BETWEEN '2014-07-18' AND '2014-07-22'
AND time(startTime) BETWEEN '03:00:00' AND '23:00:00'
AND device = 'PWR8'
GROUP BY date(startTime)) PP
ON AllDay.time = PP.time
结果:
time, ADduration, PPduration
2014-07-18, 0.66, 0.66
2014-07-20, 0.53, 0.30