postgres:在线性时间内每天获得最早和最新记录

时间:2019-04-03 16:08:10

标签: sql postgresql

我有一个带有列的表。时间戳之一。在该时间戳记上有一个索引。是否有一个有效的查询(大数据),让我每天获取最小和最大行?结果必须包含所有其他列。

还是唯一的方法是进行嵌套查询?像这样:

select * from 
   (select min(timestamp),max(timestamp) from table
   group by day)
where timestamp in (min, max)

还是编写自己的自定义postgres集成?

3 个答案:

答案 0 :(得分:0)

您可以在(timestamp::date, timestamp)上创建索引,然后尝试:

select timestamp::date, min(timestamp), max(timestamp)
from t
group by timestamp::date;

我认为它将使用索引。

如果需要所有列,请尝试使用两个索引:

  • (timestamp::date, timestamp)
  • (timestamp::date, timestamp desc)

然后做:

(select distinct on (timestamp::date) t.*
 from t
 order by timestamp::date, timestamp asc
) union all
(select distinct on (timestamp::date) t.*
 from t
 order by timestamp::date, timestamp desc
)

答案 1 :(得分:0)

您可以将表加入子查询:

select t.*
from table t
inner join (
  select min(timestamp) mint, max(timestamp) maxt 
  from table 
  group by timestamp::date
) g on (g.mint = t.timestamp or g.maxt = t.timestamp)

修改
如果存在像id这样的唯一列,则:

with cte as (
  select t.*
  from table t
  inner join (
    select min(timestamp) mint, max(timestamp) maxt 
    from table 
    group by timestamp::date
  ) g on (g.mint = t.timestamp or g.maxt = t.timestamp)
)
select t.* from cte t
where not exists (
  select 1 from cte
  where id < t.id and (mint = t.mint or maxt = t.maxt)
)

答案 2 :(得分:0)

使用不存在():


select *
from ztable t0
where not exists (
        select * from ztable t1
        WHERE t1.ztimestamp::date = t0.ztimestamp::date
        AND t1.ztimestamp < t0.ztimestamp
        )
or not exists (
        select * from ztable t2
        WHERE t2.ztimestamp::date = t0.ztimestamp::date
        AND t2.ztimestamp > t0.ztimestamp
        )
        ;

,或使用窗口功能:


select t0.*
from ztable t0
JOIN ( select timestamp
        , row_number()OVER (GROUP BY ztimestamp::date ORDER BY ztimestamp ASC) AS rn1
        , row_number()OVER (GROUP BY ztimestamp::date ORDER BY ztimestamp DESC) AS rn2
        ) tx ON tx.ztimestamp = t0.ztimestamp
WHERE tx.rn1=1 OR tx.rn2=1
        ;