在历史数据中查找日期不正确的行
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)
的索引会提高性能。
我有一个 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)
的索引会提高性能。