如何使用SQL通过值选择查询?

时间:2019-07-09 09:11:48

标签: sql postgresql

我有一个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_namedelete,则仅选择此行而不是在行之前,否则请全部选中。

对于上表,选择结果应类似于:

event_id    event_name    table     feature_id
4           delete          x       5
5           insert          x       9
5           update          x       9

因为最后一个记录是5个event_name delete。我无法为此创建SQL查询。

5 个答案:

答案 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