Поиск диапазонов, где выполняется условие

0

У меня есть таблица mysql, состоящая из значения поплавка от датчика и даты времени datetime, когда было сделано чтение. показания сохраняются с интервалом в 1 минуту (некоторые могут отсутствовать).

Я пытаюсь создать запрос, который даст мне список событий (смежных диапазонов, где значение float больше определенного порога), состоящее из метки времени первой записи в этом диапазоне, которая превышает пороговое значение, и конечной временной отметки, где значение падает ниже порогового значения.

ID      Value   Timestamp
2172846 1.0 2018-06-29 17:28:00
2172853 1.1 2018-06-29 17:29:00
2172860 1.1 2018-06-29 17:31:00
2172867 1.3 2018-06-29 17:32:00
2172874 1.3 2018-06-29 17:33:00
2172881 1.5 2018-06-29 17:34:00
2172888 1.4 2018-06-29 17:35:00
2172895 1.3 2018-06-29 17:36:00
2172902 1.2 2018-06-29 17:37:00
2172909 1.1 2018-06-29 17:38:00
2172916 1.0 2018-06-29 17:39:00
2172923 1.0 2018-06-29 17:40:00
2172930 1.0 2018-06-29 17:41:00
2172937 1.0 2018-06-29 17:42:00
2172944 1.0 2018-06-29 17:43:00
2172951 1.7 2018-06-29 17:44:00
2172958 2.0 2018-06-29 17:45:00
2172965 1.8 2018-06-29 17:46:00
2172972 1.3 2018-06-29 17:47:00
2172979 1.0 2018-06-29 17:48:00
2172986 1.0 2018-06-29 17:49:00
2172993 1.0 2018-06-29 17:50:00
2173000 1.0 2018-06-29 17:51:00
2173007 1.0 2018-06-29 17:52:00
2173014 1.0 2018-06-29 17:53:00

Я провел предварительные исследования, но я не стал намного дальше.

ожидаемый выход из набора данных образца, где порог больше 1, будет примерно таким.

start_timestamp      end_timestamp
2018-06-29 17:29:00  2018-06-29 17:39:00
2018-06-29 17:44:00  2018-06-29 17:48:00
  • 0
    Можете ли вы показать нам, что вы пытались?
  • 0
    Я не уверен, с чего начать, вот в чем проблема.
Показать ещё 9 комментариев
Теги:
time-series

3 ответа

1

В MySQL вы должны использовать переменные:

select min(timestamp), max(timestamp)
from (select t.*,
             (@grp := if(value > 1.0, @grp, @grp + 1)) as grp
      from (select t.* from t order by timestamp) t cross join
           (select @grp := 0) params
     ) t
where value > 1.0
group by grp;
  • 0
    Имеет ли значение, что мы разместили заказ на двух разных уровнях?
  • 0
    @Клубника . , , Да. Но более важным отличием является то, что вы назначаете @prev в одном выражении и используете его в другом. MySQL не гарантирует порядок вычисления выражений в SELECT .
Показать ещё 1 комментарий
1

Это проблема с пробелами и островами, если ваша функция поддержки mysql

вы можете попробовать этот запрос.

SELECT MIN('Timestamp')start_timestamp,MAX('Timestamp')end_timestamp
FROM (
  select *,MIN('Timestamp') over(order by 'Timestamp') mindt,
   ROW_NUMBER() over(order by 'Timestamp') rn
  from T
  where value > 1.0
)t1
group by (TIMESTAMPDIFF(MINUTE,mindt,'Timestamp')+1  - rn)

sqlfiddle

  • 0
    Опять же, увеличивающиеся минуты не имеют отношения к этой проблеме
0

Вот одна идея. Он возвращает очень тонкий диапазон от вашего, но, возможно, вы можете выяснить, как его настроить...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY 
,value DECIMAL(3,1)
,dt DATETIME
);

INSERT INTO my_table VALUES
(2846, 1.0, '2018-06-29 17:28:00'),
(2853, 1.1, '2018-06-29 17:29:00'),
(2860, 1.1, '2018-06-29 17:31:00'),
(2867, 1.3, '2018-06-29 17:32:00'),
(2874, 1.3, '2018-06-29 17:33:00'),
(2881, 1.5, '2018-06-29 17:34:00'),
(2888, 1.4, '2018-06-29 17:35:00'),
(2895, 1.3, '2018-06-29 17:36:00'),
(2902, 1.2, '2018-06-29 17:37:00'),
(2909, 1.1, '2018-06-29 17:38:00'),
(2916, 1.0, '2018-06-29 17:39:00'),
(2923, 1.0, '2018-06-29 17:40:00'),
(2930, 1.0, '2018-06-29 17:41:00'),
(2937, 1.0, '2018-06-29 17:42:00'),
(2944, 1.0, '2018-06-29 17:43:00'),
(2951, 1.7, '2018-06-29 17:44:00'),
(2958, 2.0, '2018-06-29 17:45:00'),
(2965, 1.8, '2018-06-29 17:46:00'),
(2972, 1.3, '2018-06-29 17:47:00'),
(2979, 1.0, '2018-06-29 17:48:00'),
(2986, 1.0, '2018-06-29 17:49:00'),
(2993, 1.0, '2018-06-29 17:50:00'),
(3000, 1.0, '2018-06-29 17:51:00'),
(3007, 1.0, '2018-06-29 17:52:00'),
(3014, 1.0, '2018-06-29 17:53:00');

SELECT MIN(dt) dt_start
     , MAX(dt) dt_end 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev=(value<=1) THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=value<=1 prev 
         FROM my_table x
            , (SELECT @prev:=null, @i:=0) vars 
        ORDER 
           BY id
     ) x 
 WHERE prev=0 
 GROUP   
    BY i;
+---------------------+---------------------+
| dt_start            | dt_end              |
+---------------------+---------------------+
| 2018-06-29 17:29:00 | 2018-06-29 17:38:00 |
| 2018-06-29 17:44:00 | 2018-06-29 17:47:00 |
+---------------------+---------------------+

Ещё вопросы

Сообщество Overcoder
Наверх
Меню