英文:
mySQL query to return minimum state duration for a given period
问题
我有一个MySQL数据库表中的以下数据,我想要计算给定时期内 state = 1
的最短持续时间,以放入Grafana的统计数据中。
在这个表片段中,期望的结果是第10行和第8行之间的timestampdiff()
,即2分钟。
id | loc | temp | state | datetime |
---|---|---|---|---|
1 | room_1 | 19.4 | 0 | 2022-12-29 18:14:09 |
2 | room_1 | 19.3 | 0 | 2022-12-29 18:15:09 |
3 | room_1 | 19.2 | 1 | 2022-12-29 18:16:09 |
4 | room_1 | 19.2 | 1 | 2022-12-29 18:17:09 |
5 | room_1 | 19.2 | 1 | 2022-12-29 18:18:09 |
6 | room_1 | 19.2 | 0 | 2022-12-29 18:19:10 |
7 | room_1 | 19.2 | 0 | 2022-12-29 18:20:10 |
8 | room_1 | 19.1 | 1 | 2022-12-29 18:21:10 |
9 | room_1 | 19.0 | 1 | 2022-12-29 18:22:10 |
10 | room_1 | 19.0 | 0 | 2022-12-29 18:23:10 |
我已经尝试了许多有问题的解决方案,但出于明显的原因,我不会在这里发布。
关于时期部分,可以使用Grafana的全局变量WHERE $__timeFilter(datetime)
,并使用它可以计算 总 持续时间 WHERE state = 1 AND $__timeFilter(datetime)
,因为记录生成是基于1分钟的基础,这使得对二进制0/1状态列求和变得容易(显然不需要state = 1
)。
我完全迷失在尝试在时期内处理持续时间。
英文:
I have the following data in a MySQL database table, and I'd like to calculate the minimum duration where state = 1
for a given period, to place into a Grafana stat.
Within this table snippet, the desired result would be the timestampdiff()
between row 10 and 8, i.e. 2 minutes.
id | loc | temp | state | datetime |
---|---|---|---|---|
1 | room_1 | 19.4 | 0 | 2022-12-29 18:14:09 |
2 | room_1 | 19.3 | 0 | 2022-12-29 18:15:09 |
3 | room_1 | 19.2 | 1 | 2022-12-29 18:16:09 |
4 | room_1 | 19.2 | 1 | 2022-12-29 18:17:09 |
5 | room_1 | 19.2 | 1 | 2022-12-29 18:18:09 |
6 | room_1 | 19.2 | 0 | 2022-12-29 18:19:10 |
7 | room_1 | 19.2 | 0 | 2022-12-29 18:20:10 |
8 | room_1 | 19.1 | 1 | 2022-12-29 18:21:10 |
9 | room_1 | 19.0 | 1 | 2022-12-29 18:22:10 |
10 | room_1 | 19.0 | 0 | 2022-12-29 18:23:10 |
I've tried numerous faulty solutions from chatGPT that I won't post here for obvious reasons.
The period part is simple enough using the Grafana global variable WHERE $__timeFilter(datetime)
and using that I can calculate the total duration WHERE state = 1 AND $__timeFilter(datetime)
because the record generation is on a 1-minute basis which makes summing the binary 0/1 state column an easy out (obviously doesn't require the state = 1
).
I'm completely lost trying to work with duration periods within a period.
答案1
得分: 0
以下是您需要的查询要求的翻译:
WITH temp_prev_state AS (
SELECT id, loc, temp, state, datetime_, LAG(state,1) OVER( ORDER BY datetime_ ) AS prev_state FROM Temperature
), latest_on_off_stateSession AS (
(SELECT * from temp_prev_state where state = '0' and prev_state = '1' ORDER BY datetime_ DESC LIMIT 1 )
UNION
(SELECT * from temp_prev_state where state = '1' and prev_state = '0' ORDER BY datetime_ DESC LIMIT 1 )
), lat_on_off_prev_dt AS (
SELECT *, LAG(datetime_,1) OVER( ORDER BY datetime_ ) AS prev_datetime_ FROM latest_on_off_stateSession
)
select id, loc, temp, state, datetime_, ABS(TIMESTAMPDIFF(MINUTE,datetime_ ,prev_datetime_)) AS abs_Time_Diff_Mins FROM lat_on_off_prev_dt
在此处查看演示:https://dbfiddle.uk/Sm7q9P7Y
英文:
The query requirements that you had was bit complex, I had to use windows function - LAG to get the results. Below is the query that you need.
WITH temp_prev_state AS (
SELECT id, loc, temp, state, datetime_, LAG(state,1) OVER( ORDER BY datetime_ ) AS prev_state FROM Temperature
), latest_on_off_stateSession AS (
(SELECT * from temp_prev_state where state = '0' and prev_state = '1' ORDER BY datetime_ DESC LIMIT 1 )
UNION
(SELECT * from temp_prev_state where state = '1' and prev_state = '0' ORDER BY datetime_ DESC LIMIT 1 )
), lat_on_off_prev_dt AS (
SELECT *, LAG(datetime_,1) OVER( ORDER BY datetime_ ) AS prev_datetime_ FROM latest_on_off_stateSession
)
select id, loc, temp, state, datetime_, ABS(TIMESTAMPDIFF(MINUTE,datetime_ ,prev_datetime_)) AS abs_Time_Diff_Mins FROM lat_on_off_prev_dt
Check the demo here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论