我有一个SQL日志表,用于记录数据库表事件。 (插入,更新,删除)
event_id event_name table feature_id
1 insert x 5
2 update x 5
3 update x 5
4 delete x 5
5 insert x 9
5 update x 9
所以我要选择此表。但是,对于feature_id:
event_name
是delete
,则仅选择此行而不是在行之前,否则请全部选中。对于上表,选择结果应类似于:
event_id event_name table feature_id
4 delete x 5
5 insert x 9
5 update x 9
因为最后一个记录是5个event_name delete
。我无法为此创建SQL查询。
答案 0 :(得分:0)
请尝试使用cte,如下所示
with cte as
(
select min(event_id) from table_name where event_name='delete'
) select * from table_name where event_id>=( select event_id from cte)
或仅使用子查询
select * from table_name where event_id>=(select min(event_id) from table_name where event_name='delete')
答案 1 :(得分:0)
这应该有效:
select * from TABLENAME
where event_name = 'Delete'
union
select * from TABLENAME
where event_id >= (select event_id from TABLENAME where event_name = 'Delete')
答案 2 :(得分:0)
如果Table1具有具有'delete'值的多个event_name,我将使用max(event_id)防止错误。如果我省略max,则子查询返回多个值。您可以使用其他聚合,例如。分钟(event_id)。
with cte as
(
select event_id from Table1 where event_name = 'delete'
)
select * from Table1 where event_id >= (select max(event_id) from cte)
答案 3 :(得分:0)
使用CTE获取具有event_name ='delete'的最大event_id和最大event_id之差,并在WHERE子句中使用它:
with cte as (
select
(max(event_id) - max(case when event_name = 'delete' then event_id else 0 end)) dif,
max(case when event_name = 'delete' then event_id else 0 end) maxid
from tablename where feature_id = 5
)
select *
from tablename t
where (feature_id <> 5 or event_id = (select maxid from cte))
or (select dif from cte) <> 0
请参见demo。
结果:
> event_id | event_name | table | feature_id
> -------: | :--------- | :---- | ---------:
> 4 | delete | x | 5
> 5 | insert | x | 9
> 5 | update | x | 9
如果feature_id = 5另有一行,例如:
INSERT INTO tablename (event_id,event_name,"table",feature_id) VALUES
(6,'update','x',5)
那么结果是:
> event_id | event_name | table | feature_id
> -------: | :--------- | :---- | ---------:
> 1 | insert | x | 5
> 2 | insert | x | 5
> 3 | insert | x | 5
> 4 | delete | x | 5
> 5 | insert | x | 9
> 5 | update | x | 9
> 6 | update | x | 5
答案 4 :(得分:0)
假设'delete'
作为最后一条记录只能出现一次,则可以执行以下操作:
select *
from table_name
where event_id >= all (select t2.event_id
from table_name t2
where t2.feature_id = t.feature_id and
t2.event_name = 'delete'
);
否则,这会变得更加复杂:
select t.*
from (select t.*,
first_value(event_name) over (partition by feature_id order by event_id desc) as last_event_name,
row_number() over (partition by feature_id order by event_id desc) as seqnum
from my_table t
) t
where (last_event_name = 'delete' and seqnum = 1) or
(last_event_name <> 'delete');
where
子句可以简化为:
where last_event_name <> 'delete' or seqnum = 1