让我们说我有一张看起来像这样的桌子,在几秒钟内给我一些各种活动的时间。
event_time
----------
11
14
18
20
25
39
42
43
50
我正在尝试提供一个查询,该查询将从此表中为我提供一组行,其中每行与结果中的其他行相隔至少10秒。
期望的结果是:
event_time
----------
11
25
39
50
包含event_time=11
的行,因为它前面没有任何内容。 event_time=25
的行是下一个要返回的行,因为它是距离event_time=11
行的第一行至少10秒。
我正在使用Postgres。我可以使用递归查询/ CTE执行此操作,但如果不使用ORDER BY,LIMIT等子句就无法完成此操作,Postgres显然不允许在递归查询中使用这些。
答案 0 :(得分:2)
您可以使用plpgsql,这对于大型数据集来说似乎很简单且非常有效(与假设的递归查询相比)。
create or replace function strain_events()
returns setof events language plpgsql as $$
declare
curr record;
prev int;
begin
for curr in
select *
from events
order by 1
loop
if prev is null or curr.event_time >= prev + 10 then
return next curr;
prev = curr.event_time;
end if;
end loop;
end $$;
select * from strain_events();
答案 1 :(得分:2)
我可以使用递归查询/ CTE执行此操作,但如果不使用ORDER BY,LIMIT等子句就无法完成此操作,Postgres显然不允许在递归查询中使用这些。
with recursive
t(x) as ( --Test data
select * from unnest('{11,14,18,20,25,39,42,43,50,55,60,61,69,70,71}'::int[])
order by random()),
r(x) as (
select min(x) as x from t
union all
(select t.x from t join r on (t.x >= r.x + 10) order by t.x limit 1))
select * from r;
答案 2 :(得分:0)
我认为此查询可以正常工作
select distinct event_time_b
from
(
select event_time_a , min(event_time_b) event_time_b
from
(
select a.event_time event_time_a , b.event_time event_time_b , b.event_time-a.event_time diff
from (select 0 as event_time union select event_time from so_ques) a , so_ques b
where a.event_time<>b.event_time
and b.event_time-a.event_time>=10
order by a.event_time
) a
group by event_time_a
order by event_time_a
) a
order by 1
;
表名= so_ques (为测试而创建)