我有一张包含以下数据的表格:
mysql> select * from playground order by macAddress, locatedAt;
+------------+---------------------+--------------+
| macAddress | locatedAt | status |
+------------+---------------------+--------------+
| device1 | 2014-08-11 01:20:27 | connected |
| device1 | 2014-08-11 01:30:27 | connected |
| device1 | 2014-08-11 01:40:27 | disconnected |
| device1 | 2014-08-11 01:49:27 | connected |
| device1 | 2014-08-11 01:50:27 | disconnected |
| device1 | 2014-08-11 01:55:27 | disconnected |
| device1 | 2014-08-11 02:05:27 | disconnected |
| device1 | 2014-08-11 02:17:27 | disconnected |
| device1 | 2014-08-11 02:27:27 | disconnected |
| device1 | 2014-08-11 02:47:27 | connected |
| device1 | 2014-08-11 02:57:27 | connected |
| device1 | 2014-08-11 03:50:27 | disconnected |
我需要总结如下:
date | hour | connected | disconnected | previouslyConnected
2014-08-11 | 1 | 1 | 0 | 0
2014-08-11 | 2 | 1 | 0 | 0
2014-08-11 | 3 | 0 | 0 | 1
只要设备在一小时内连接一次,断开连接无关紧要。如果设备在给定小时内仅具有“断开连接”条目,则它处于“断开连接”状态。如果设备断开连接,则如果同一设备在前一小时处于“已连接”状态,则它将进入先前连接状态。否则它本身就处于“断开连接”状态。
在第三行中,device1处于“previousConnected”状态,因为此设备在前一小时(小时2)已连接。
我无法获取'previousConnected'状态设备;
使用我当前的查询,我可以获得除最后一列之外的所有内容。
SELECT TEMP.day, TEMP.hour,
SUM(CASE WHEN TEMP.connected > 0 THEN 1 ELSE 0 END) as connected,
SUM(CASE WHEN TEMP.unconnected > 0 AND TEMP.connected < 1 THEN 1 ELSE 0 END) as unconnected
from
(SELECT
DATE(locatedAt) day,
HOUR(locatedAt) hour,
macAddress,
SUM(CASE WHEN status='connected' THEN 1 ELSE 0 END) as connected,
SUM(CASE WHEN status='disconnected' THEN 1 ELSE 0 END) as unconnected
FROM
playground
GROUP BY
DATE(locatedAt), HOUR(locatedAt), macAddress) as TEMP
GROUP BY TEMP.day, TEMP.hour;
任何指针?
答案 0 :(得分:0)
您可以使用用户定义的变量来检查以前的结果状态,在内部查询中我使用GROUP_CONCAT
以locatedAt
的降序连接所有状态,因此它将生成逗号按降序排列的状态字符串并使用SUBSTRING_INDEX
我选择了第一个状态,这是机器的最后一个状态,我已经存储了表达式SUBSTRING_INDEX(GROUP_CONCAT(
状态{{1}的最后一个状态在ORDER BY locatedAt DESC),',',1)
变量中,以及一个@prev
语句来检查它是否在前一行中连接了show 1 else 0
CASE
Fiddle Demo
答案 1 :(得分:0)
SELECT
day,
hour,
connected,
disconnected,
previouslyConnected
FROM
( SELECT
t.day,
t.hour,
CASE WHEN t.connected > 0 THEN 1 ELSE 0 END AS connected,
IF((CASE WHEN t.connected > 0 THEN 1 ELSE 0 END) = 0 AND @A = 0, 1, 0) AS disconnected,
IF((CASE WHEN t.connected > 0 THEN 1 ELSE 0 END) = 0 AND @A = 1, 1, 0) AS previouslyConnected,
@A := CASE WHEN t.connected > 0 THEN 1 ELSE 0 END
FROM
( SELECT
DATE(locatedAt) AS 'day',
HOUR(locatedAt) AS 'hour',
SUM(CASE WHEN status = 'connected' THEN 1 ELSE 0 END) AS connected,
SUM(CASE WHEN status = 'disconnected' THEN 1 ELSE 0 END) AS unconnected
FROM playground
GROUP BY HOUR(locatedAt) , DATE(locatedAt)
) t
) t1;
+-------------+------+-----------+--------------+---------------------+
|date | hour | connected | disconnected | previouslyConnected |
+-------------+------+-----------+--------------+---------------------+
|2014-08-11 | 1 | 1 | 0 | 0 |
|2014-08-11 | 2 | 1 | 0 | 0 |
|2014-08-11 | 3 | 0 | 0 | 1 |
+-------------+------+-----------+--------------+---------------------+
答案 2 :(得分:0)
你可以在没有@variables的情况下通过LEFT JOIN
前一个小时来完成:
SELECT DATE(p.locatedAt) day,
HOUR(p.locatedAt) hour,
SUM(p.status='connected') != 0 connected,
SUM(p.status='disconnected')
AND NOT SUM(p.status='connected') unconnected,
SUM(p.status='disconnected')
AND NOT SUM(p.status='connected')
AND COALESCE(SUM(pp.connected),0) != 0 previously_connected
FROM playground p
LEFT JOIN (
SELECT EXTRACT(DAY_HOUR FROM locatedAt) d_h,
SUM(status='connected') connected
FROM playground
GROUP BY EXTRACT(DAY_HOUR FROM locatedAt),
macAddress
) pp
ON pp.d_h = EXTRACT(DAY_HOUR FROM p.locatedAt) - 1
GROUP BY day,
hour
ORDER BY day,
hour