Postgresql提取每个ID的最后一行

6vl6ewon  于 2023-02-22  发布在  PostgreSQL
关注(0)|答案(5)|浏览(440)

假设我有下一个数据

id    date          another_info
  1     2014-02-01         kjkj
  1     2014-03-11         ajskj
  1     2014-05-13         kgfd
  2     2014-02-01         SADA
  3     2014-02-01         sfdg
  3     2014-06-12         fdsA

我想为每个ID提取最后的信息:

id    date          another_info
  1     2014-05-13         kgfd
  2     2014-02-01         SADA
  3     2014-06-12         fdsA

我怎么能做到呢?

rkkpypqq

rkkpypqq1#

最有效的方法是使用Postgres的distinct on运算符

select distinct on (id) id, date, another_info
from the_table
order by id, date desc;

如果您想要一个跨数据库工作的解决方案(但效率较低),可以使用窗口函数:

select id, date, another_info
from (
  select id, date, another_info, 
         row_number() over (partition by id order by date desc) as rn
  from the_table
) t
where rn = 1
order by id;

在大多数情况下,使用窗口函数的解决方案比使用子查询要快。

sr4lhrrt

sr4lhrrt2#

select * 
from bar 
where (id,date) in (select id,max(date) from bar group by id)
  • 在PostgreSQL、MySQL中测试 *
y4ekin9u

y4ekin9u3#

我发现这是最快的解决方案:

SELECT t1.*
   FROM yourTable t1
     LEFT JOIN yourTable t2 ON t2.tag_id = t1.tag_id AND t2.value_time > t1.value_time
  WHERE t2.tag_id IS NULL
5kgi1eie

5kgi1eie4#

对于大多数情况,最有效的方法是使用GROUP BY

我看到了公认的答案,它确定使用distinct on (id) id是解决问题中描述的问题的最有效的方法,但我相信它是非常不准确的。遗憾的是,我无法从POSTGRES文档中找到任何有用的见解,但我确实找到了this article,它引用了一些其他的,并提供了示例,而
GROUPBY方法肯定会带来更好的性能
我们曾在工作中讨论过这个问题,并在一个表上做了一些实验,该表保存了一些关于标签 Flink 的数据,有4,114,692行,并具有基于tag_id和timestamp的索引(独立索引)

以下是查询:

1.使用字典:

select distinct on (tag_id) tag_id, timestamp, some_data 
from blinks 
order by id, timestamp desc;

2.使用CTE + group by + join:

`with blink_last_timestamp as (
     select tag_id, max(timestamp) as max_timestamp
     from blinks 
     group by tag_id )
 select bl.tag_id, max_timestamp, some_data
 from blink_last_timestamp bl 
 join blinks b on 
     b.tag_id = bl.tag_id and 
     bd.timestamp = bl.max_timestamp`

结果是明确的,并且支持此场景的第二种解决方案(在我看来,这是非常通用的),
显示其1655.991毫秒(00:01.656)比16723.346毫秒(00:16.723)快了10倍(!),当然也提供了相同的数据。

q43xntqr

q43xntqr5#

按id分组并使用任何聚合函数来满足最后一条记录的条件。

select  id, max(date), another_info
from the_table
group by id, another_info

相关问题