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

Рейтинг: 0Ответов: 2Опубликовано: 26.02.2023

Всем привет, подскажите пожалуйста, кто знает. Есть таблица вот такого содержание введите сюда описание изображения

Я хочу получить данные типа

datetime status
2023-02-26 21:24:01 0
2023-02-26 21:12:02 1
2023-02-26 21:06:02 0
2023-02-26 20:48:01 1

т.е. нужны только периоды изменения значения, их повторы не нужны. Как составить запрос чтобы получить желаемое и возможно ли это вообще?

Ответы

▲ 2

Тут путает именно то, что дата отображена по убыванию и не понятно как записи вносились в базу. Скорее это какой-то журнал и тут надо поймать изменение status со следующей датой, хотя сути это не меняет. Автор уже ответил на свой вопрос, а я просто оставлю здесь свой вариант решения:

-- искомая таблица
CREATE TABLE testTable (
  date DATETIME NOT NULL,
  status int NOT NULL
);

-- данные
INSERT INTO testTable VALUES ('2023-02-26 21:24:01', 0);
INSERT INTO testTable VALUES ('2023-02-26 21:21:01', 0);
INSERT INTO testTable VALUES ('2023-02-26 21:18:02', 0);
INSERT INTO testTable VALUES ('2023-02-26 21:15:02', 0);
INSERT INTO testTable VALUES ('2023-02-26 21:12:02', 1);
INSERT INTO testTable VALUES ('2023-02-26 21:09:01', 1);
INSERT INTO testTable VALUES ('2023-02-26 21:06:02', 0);
INSERT INTO testTable VALUES ('2023-02-26 21:03:01', 0);
INSERT INTO testTable VALUES ('2023-02-26 21:00:02', 0);
INSERT INTO testTable VALUES ('2023-02-26 20:57:01', 0);
INSERT INTO testTable VALUES ('2023-02-26 20:54:01', 0);
INSERT INTO testTable VALUES ('2023-02-26 20:51:01', 0);
INSERT INTO testTable VALUES ('2023-02-26 20:48:01', 1);
INSERT INTO testTable VALUES ('2023-02-26 20:45:02', 0);
INSERT INTO testTable VALUES ('2023-02-26 20:42:01', 0);
INSERT INTO testTable VALUES ('2023-02-26 20:39:01', 0);

-- выборка
SELECT 
  t.date,
  t.status
FROM 
  (
    SELECT 
      date,
      status,
      LAG(status) OVER (ORDER BY date DESC) AS nextStatus -- следующий статус
    FROM testTable
  ) t
WHERE
  t.status != t.nextStatus -- либо есть разница
  OR t.nextStatus IS NULL -- либо последняя
ORDER BY
  t.date DESC;
▲ 1

решил примерно так

WITH T1 AS (
    SELECT status
         , date
         , (LAG(status, 1) OVER ()) AS last_status 
    FROM data
    ORDER BY date DESC
)
SELECT * 
FROM T1 
WHERE status <> last_status 
    OR last_status IS NULL;

Запрос включает функцию LAG (вроде как с 8.0.22 доступна), благодаря которой получаем значение прошлой строки. Весь результат в табличное выражение. В выборке сравниваем текущий status с прошлым.