我有一个表,其中列活动的值分别为“ ON”和“ OFF”,而另一列日期时间为
。id(AUTOINCREMENT) id_device activity datetime
1 a ON 2017-05-26 22:00:00
2 b ON 2017-05-26 05:00:00
3 a OFF 2017-05-27 04:00:00
4 b OFF 2017-05-26 08:00:00
5 a ON 2017-05-28 12:00:00
6 a OFF 2017-05-28 15:00:00
我需要每天获取总计开机时间
day id_device total_minutes_on
2017-05-26 a 120
2017-05-26 b 180
2017-05-27 a 240
2017-05-27 b 0
2017-05-28 a 180
2017-05-28 b 0
我已经搜索并尝试了其他帖子的答案,我尝试了TimeDifference,并获得了正确的总时间。 我找不到按日期分组总时间的方法
感谢您的帮助
答案 0 :(得分:0)
我并不是将其发布为一个明确的答案,而是对我来说是一个实验,希望您会发现对您的情况有用。我还要提及的是,我正在使用的MySQL数据库版本已经很旧了,因此至少可以说,我使用的方法也是非常手动的。
首先让我们提取您的预期输出:
day
中的日期值需要在id_device a
和b
中重复两次。OFF
。我想出的是这样的:
SELECT * FROM
(SELECT DATE(datetime) dtt FROM mytable GROUP BY DATE(datetime)) a,
(SELECT id_device FROM mytable GROUP BY id_device) b
ORDER BY dtt,id_device;
上面的查询将返回以下结果:
+------------+-----------+
| dtt | id_device |
+------------+-----------+
| 2017-05-26 | a |
| 2017-05-26 | b |
| 2017-05-27 | a |
| 2017-05-27 | b |
| 2017-05-28 | a |
| 2017-05-28 | b |
+------------+-----------+
*以上仅适用于表格中的所有日期。如果您想获得所有日期,而不管是否有活动,建议您创建一个日历表(请参阅:Generating a series of dates)。
因此这成为基本查询。然后,我添加了一个外部查询,以使上面的查询与原始数据表左连接:
SELECT v.*,
GROUP_CONCAT(w.activity ORDER BY w.datetime SEPARATOR ' ') activity,
GROUP_CONCAT(TIME_TO_SEC(TIME(w.datetime)) ORDER BY w.datetime SEPARATOR ' ') tr
FROM
-- this was the first query
(SELECT * FROM
(SELECT DATE(datetime) dtt FROM mytable GROUP BY DATE(datetime)) a,
(SELECT id_device FROM mytable GROUP BY id_device) b
ORDER BY a.dtt,b.id_device) v
--
LEFT JOIN
mytable w
ON v.dtt=DATE(w.datetime) AND v.id_device=w.id_device
GROUP BY DATE(v.dtt),v.id_device
查询中的新增功能是对从datetime列提取的活动和时间值添加了GROUP_CONCAT
操作,该操作和时间值转换为秒值。您会注意到,在两个GROUP_CONCAT
中都有一个相似的ORDER BY
条件,这对于获取确切的对应值很重要。
上面的查询将返回以下结果:
+------------+-----------+----------+-------------+
| dtt | id_device | activity | tr |
+------------+-----------+----------+-------------+
| 2017-05-26 | a | ON | 79200 |
| 2017-05-26 | b | ON OFF | 18000 28800 |
| 2017-05-27 | a | OFF | 14400 |
| 2017-05-27 | b | (NULL) | (NULL) |
| 2017-05-28 | a | ON OFF | 43200 54000 |
| 2017-05-28 | b | (NULL) | (NULL) |
+------------+-----------+----------+-------------+
从这里,我在外面添加了另一个查询,以计算多少分钟并尝试获得预期的结果:
SELECT dtt,id_device,
CASE
WHEN SUBSTRING_INDEX(activity,' ',1)='ON' AND SUBSTRING_INDEX(activity,' ',-1)='OFF'
THEN (SUBSTRING_INDEX(tr,' ',-1)-SUBSTRING_INDEX(tr,' ',1))/60
WHEN activity='ON' THEN 1440-(tr/60)
WHEN activity='OFF' THEN tr/60
WHEN activity IS NULL AND tr IS NULL THEN 0
END AS 'total_minutes_on'
FROM
-- from the last query
(SELECT v.*,
GROUP_CONCAT(w.activity ORDER BY w.datetime SEPARATOR ' ') activity,
GROUP_CONCAT(TIME_TO_SEC(TIME(w.datetime)) ORDER BY w.datetime SEPARATOR ' ') tr
FROM
-- this was the first query
(SELECT * FROM
(SELECT DATE(datetime) dtt FROM mytable GROUP BY DATE(datetime)) a,
(SELECT id_device FROM mytable GROUP BY id_device) b
ORDER BY a.dtt,b.id_device) v
--
LEFT JOIN
mytable w
ON v.dtt=DATE(w.datetime) AND v.id_device=w.id_device
GROUP BY DATE(v.dtt),v.id_device
--
) z
我要做的最后一部分是,如果activity
值在同一天同时具有ON
和OFF
,那么(OFF
-ON
)/ 60secs =总分钟数。如果activity
的值仅为ON
,则'24:00:00'的分钟值> 24小时* 60分钟= 1440-(ON
/ 60secs)=总分钟数,并且如果活动仅OFF
,我只是将秒转换为分钟,因为无论如何一天都是从00:00:00开始。
+------------+-----------+------------------+
| dtt | id_device | total_minutes_on |
+------------+-----------+------------------+
| 2017-05-26 | a | 120 |
| 2017-05-26 | b | 180 |
| 2017-05-27 | a | 240 |
| 2017-05-27 | b | 0 |
| 2017-05-28 | a | 180 |
| 2017-05-28 | b | 0 |
+------------+-----------+------------------+
希望这会给您一些想法。 ;)