在历史数据中查找日期不正确的行

Seek rows with incorrect dates in historic data

我有一个 table 这是一个历史日志,最近我修复了一个错误,该错误写在 table 一个不正确的日期,这些日期应该是相关的,但在某些情况下有不是那个日期,比上一个日期早很多。

如何获取与每个 entity_id 不相关的所有行?在下面的示例中,我应该得到第 5 行和第 10 行。 table 有数百万行和数千个不同的实体。我想比较按日期和 id 排序的结果,但这是很多手工工作。

| id     | entity_id   | time_stamp    |
|--------|-------------|---------------|
| 1      | 7           | 2019-01-22    |
| 2      | 9           | 2019-01-05    |
| 3      | 6           | 2019-03-14    |
| 4      | 9           | 2019-04-20    |
| 5      | 6           | 2015-10-04    | WRONG
| 6      | 9           | 2019-07-15    |
| 7      | 3           | 2019-07-04    |
| 8      | 7           | 2019-06-01    |
| 9      | 6           | 2019-11-04    |
| 10     | 7           | 2019-03-04    | WRONG

有没有什么函数可以通过实体id来比较之前的日期?我完全迷失在这里,不知道如何清理数据。顺便说一下,数据库是MYSQL。

如果你是运行MySQL8.0,可以用lag();这个想法是在具有相同 entity_id 的组内按 id 对记录进行排序,然后过滤当前时间戳小于前一个时间戳的记录:

select t.*
from (
    select t.*, lag(time_stamp) over(partition by entity_id order by id) lag_time_stamp
    from mytable t
) t
where time_stamp < lag_time_stamp

在早期版本中,一种选择是使用相关子查询来获取之前的时间戳:

select t.*
from mytable t
where time_stamp < (
    select time_stamp 
    from mytable t1 
    where t1.entity_id = t.entity_id and t1.id < t.id
    order by id desc
    limit 1
)
SELECT s1.*
FROM sourcetable s1
WHERE EXISTS ( SELECT NULL
               FROM sourcetable s2
               WHERE s1.id < s2.id
                 AND s1.entity_id = s2.entity_id
                 AND s1.time_stamp > s2.time_stamp )

(entity_id, id, time_stamp)(entity_id, time_stamp, id)的索引会提高性能。