Группировать последовательные строки в две строки с началом и концом

#sql

#sql

Вопрос:

Моя цель — отфильтровать выбранные данные из огромной таблицы. Я работаю с огромной таблицей, содержащей миллионы строк данных, и мне нужно найти эффективный способ выбора нужных мне данных. Таблица содержит значения различных измерений, включая временную метку и имя:

Имя временная метка Значение
температура 15:35 22
Скорость 15:35 50
температура 15:36 22
Скорость 15:36 50
температура 15:37 22
Скорость 15:37 50
Скорость 15:38 50
температура 15:38 25

Я работаю с такими инструкциями

 Select * from MeasurementValues where Name like 'speed'
 

Это возвращает мне значения, которые я затем помещаю в диаграмму. Проблема в том, что для размещения всех точек на этой диаграмме требуется слишком много времени. Поскольку точки в основном остаются с одним и тем же значением, я хочу добавить фильтрацию в свой оператор. я хочу группировать последовательные записи с одинаковыми значениями и возвращать только первую и последнюю запись.
Например, если я хочу иметь значения для скорости, мне нужны только результаты:

Имя временная метка Значение
Скорость 15:35 50
Скорость 15:38 50

Для значений температуры я хочу получить следующие результаты:

Имя временная метка Значение
температура 15:35 22
температура 15:37 22
температура 15:38 25

Я надеюсь, что вы понимаете мою проблему и можете мне в этом помочь. Мои знания SQL довольно просты.

С уважением

Комментарии:

1. почему для ‘temperatire’ у вас есть 3 записи?

2. Первый — это Первый ряд с температурой 22, Второй — последний ряд со значением 22. После этого у меня есть значение 25, поэтому его тоже нужно получить

3. тогда как насчет третьей строки?

4. Извините, я отредактировал это. Значение изменяется на 25. Вот почему я тоже вставил эту строку туда.

Ответ №1:

Вы можете использовать lead() и lag() :

 select mv.*
from (select mv.*,
             lag(value) over (partition by name order by timestamp) as prev_value,
             lead(value) over (partition by name order by timestamp) as next_value
      from MeasurementValues mv
      where name = 'speed'
     ) mv
where (prev_value is null or prev_value <> value) or
      (next_value is null or next_value <> value);
 

Комментарии:

1. Я должен проверить это завтра. Опережение и отставание для меня в новинку, но, похоже, это делает именно то, что я хочу

2. Спасибо, это сработало отлично и было намного эффективнее, чем мой предыдущий код.