Игнорировать последующие эквивалентные строки в mysql select - PullRequest
0 голосов
/ 19 ноября 2018

Мне нужно удалить избыточность в исторических данных журнала.Поэтому, учитывая следующую таблицу:

 --------------------------------------
|  entity_id  |  action  |   date      |
 --------------------------------------
|      1      |    'A'   | 2018-01-01  |
|x     1      |    'A'   | 2018-01-01  |
|      1      |    'B'   | 2018-01-01  |
|      1      |    'A'   | 2018-01-02  |
|      8      |    'A'   | 2018-01-02  |
|x     1      |    'A'   | 2018-01-03  |
|x     8      |    'A'   | 2018-01-04  |
|x     1      |    'A'   | 2018-01-05  |
|      1      |    'B'   | 2018-01-05  |
 --------------------------------------

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

 --------------------------------------
|  entity_id  |  action  |   date      |
 --------------------------------------
|      1      |    'A'   | 2018-01-01  |
|      1      |    'B'   | 2018-01-01  |
|      1      |    'A'   | 2018-01-02  |
|      8      |    'A'   | 2018-01-02  |
|      1      |    'B'   | 2018-01-05  |
 --------------------------------------

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

Спасибо

edit: В основном, для сущности 1 последовательность действий в журнале равна A->A->B->A->A->A->B, я хотел бы выбратьвозвращает строку с этими действиями A->B->A->B

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Вы хотите строки с самым последним действием для каждого объекта.Я бы сделал:

select t.*
from t
where t.date = (select min(t2.date)
                from t t2
                where t2.entity_id = t.entity_id and t2.action = t.action
               );

РЕДАКТИРОВАТЬ:

В MySQL 8+, вы бы просто использовали lag():

select t.*
from (select t.*,
             lag(action) over (partition by entity_id order by date) as prev_action
      from t
     ) t
where prev_action is null or prev_action > action;

Вы можете сделать что-то подобное в предыдущемверсии MySQL, но оконные функции проще, если доступны.

0 голосов
/ 19 ноября 2018

Это будет, если строки будут добавлены в порядке даты.

select entity_id, action, min(date)
from table
group by entity id, action
...