我需要删除历史日志数据中的冗余。因此,给出下表:
--------------------------------------
| 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查询的人将如何处理呢?
谢谢
编辑:基本上,对于实体1,日志中动作的连续性为A->A->B->A->A->A->B
,我希望有一个选择返回带有这些动作A->B->A->B
的行
答案 0 :(得分:0)
这是如果按日期顺序添加行。
select entity_id, action, min(date)
from table
group by entity id, action
答案 1 :(得分:-1)
您希望每个实体的行都具有最新操作。我会的:
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中执行类似的操作,但是窗口功能(如果可用)更简单。