我正在努力解决MySQL问题,而不会发疯。不知道这是否可行。 数据来自门/光传感器,以检测厕所是否被占用。当门关闭或打开时,我会收到信息+灯光信息。如果我有关门且灯光<10的信息,则表示厕所不被占用;如果灯光> 10,则厕所是被占用的;如果门打开,则厕所不被占用。
以下是我的数据示例:
id wc_id door_open light time
138 0 1 64 2018-10-10 12:28:51
139 0 0 58 2018-10-10 12:34:00
140 0 0 54 2018-10-10 12:34:38
141 0 1 68 2018-10-10 12:35:11
142 0 1 3 2018-10-10 12:35:36
143 0 0 60 2018-10-10 12:37:56
144 0 0 60 2018-10-10 12:37:57
145 0 0 57 2018-10-10 12:38:30
146 0 1 65 2018-10-10 12:43:53
147 0 1 3 2018-10-10 12:44:17
148 0 0 63 2018-10-10 13:10:55
149 0 0 59 2018-10-10 13:11:16
150 0 1 71 2018-10-10 13:12:09
151 0 1 4 2018-10-10 13:12:14
152 0 1 1 2018-10-10 13:15:07
153 0 0 62 2018-10-10 13:17:18
154 0 0 58 2018-10-10 13:18:01
155 0 1 68 2018-10-10 13:19:20
156 0 1 3 2018-10-10 13:19:56
157 0 1 42 2018-10-10 13:26:41
158 0 0 63 2018-10-10 13:26:44
159 0 0 58 2018-10-10 13:27:39
160 0 1 71 2018-10-10 13:27:40
161 0 1 3 2018-10-10 13:28:37
最后的想法是只有一系列door_open从0到1,不可能连续有两个0或两个1。
因此,无论轻度值如何,我都需要保持door_open=0
的前light>10
和{{1}之后的door_open=1
,以及door_open=1
之后的第door_open=0
。
MySQL可以吗?我使用的是MariaDB 10.3.9。
感谢您的想法。
输出应为:
id wc_id door_open light time
139 0 0 58 12:34:00
141 0 1 68 12:35:11
143 0 0 60 12:37:56
146 0 1 65 12:43:53
148 0 0 63 13:10:55
150 0 1 71 13:12:09
153 0 0 62 13:17:18
155 0 1 68 13:19:20
158 0 0 63 13:26:44
160 0 1 71 13:27:40
(我简化了时间,在这里并不重要) 这是fiddle
答案 0 :(得分:1)
此查询应执行您想要的操作。它使用一个MySQL变量将door_open
的值延迟1行,然后返回其中door_open=0
与light>10
之间的行,其中door_open=1
在door_open=1
之后,第一个door_open=0
在SELECT events.*, @door_open := door_open
FROM events
JOIN (SELECT @door_open := 1) do
WHERE @door_open = 0 AND door_open = 1 OR
@door_open = 1 AND door_open = 0 AND light > 10
之后,无论任何亮度值:
id toilet_id door_open light time @door_open := door_open
101 0 false 62 2018-10-10T11:39:31Z 0
103 0 true 69 2018-10-10T11:39:34Z 1
104 0 false 62 2018-10-10T11:42:16Z 0
106 0 true 68 2018-10-10T11:45:50Z 1
109 0 false 56 2018-10-10T12:13:11Z 0
输出(根据您的提琴数据):
var url_full = "http://foo.com/?q=&min=0&max=789"
var url_clean = url_full.replace('&min='+ /\d+/,'');
var url_clean = url_full.replace('&max='+ /\d+/,'');
console.log(url_clean);
var regex = /\d+/g;
var string = "http://foo.com/?q=&min=0&max=789";
var matches = string.match(regex); // creates array from matches
for(var s=0;s<matches.length;s++){
console.log(matches[s]);
}
document.write(matches);
答案 1 :(得分:0)
在研究尼克解决方案之后,这是我问题的潜在答案。我不得不重新排序我的表(删除行之后),以避免订单混乱。
select es.id,
es.idNext,
es.toilet_id,
es.time,
es.nextTime,
timediff(es.nextTime, es.time) AS duration
from (
SELECT id, toilet_id, time,
@door_open := door_open as door_open,
lead(id, 1) OVER(ORDER BY id) idNext,
lead(time, 1) OVER(ORDER BY id) nextTime
FROM events e
JOIN (SELECT @door_open := 1) do
WHERE @door_open = 0 AND door_open = 1 OR
@door_open = 1 AND door_open = 0 AND light > 20
) es
where
es.door_open=0 and
timediff(es.nextTime, es.time)>5
接下来的事情是更新查询,以使用Toilet_id上的分区将数据与每个id分开。