Выбор при изменении значения

#mysql #sql #datetime #select #gaps-and-islands

#mysql #sql #дата и время #выберите #пробелы и острова

Вопрос:

У меня есть таблица, которая выглядит следующим образом в MySQL базе данных:

 CREATE TABLE IF NOT EXISTS Example(Batch_Num int, Time DATETIME);
INSERT INTO Example 
VALUES
(1,'2020-12-04 05:06:12'), 
(1,'2020-12-04 05:06:13'), 
(1,'2020-12-04 05:06:14'), 
(2,'2020-12-04 05:06:20'), 
(2,'2020-12-04 05:07:12'), 
(2,'2020-12-04 05:07:20'), 
(1,'2020-12-04 05:07:25'), 
(1,'2020-12-04 05:07:35'), 
(3,'2020-12-04 05:07:35');
 

Я хотел бы выбрать все строки, где значение Batch_Num отличается от предыдущего значения, включая первое:

  ---------- ----------------------- 
| BatchNum |      Change_Time      |
 ---------- ----------------------- 
|        1 | '2020-12-04 05:06:12' |
|        2 | '2020-12-04 05:06:20' |
|        1 | '2020-12-04 05:07:25' |
|        3 | '2020-12-04 05:07:35' |
 ---------- ----------------------- 
 

Возможно, есть ключевое слово для доступа к предыдущей строке для сравнения с текущей строкой? Или какой-либо другой способ сравнить строку со строкой перед ней?

Ответ №1:

Это своего рода проблема пробелов и островов. Острова — это соседние строки, которые имеют одинаковые batchnum значения, и вам нужно начало каждого острова.

Здесь, вероятно, самый простой подход lag() :

 select *
from (
    select e.*,
        lag(batchnum) over(order by time) lag_batchnum
    from example e
) e
where not lag_batchnum <=> batchnum
 

Обратите внимание, что для этого требуется MySQL 8.0. В более ранних версиях одна альтернатива использует коррелированный подзапрос:

 select e.*
from example e
where not batchnum <=> (
    select e1.batchnum
    from example e1
    where e1.time < e.time
    order by e1.time desc
    limit 1
)
 

Вот демонстрация на скрипке DB.