programing

각 ID에 대한 Postgresql 추출 마지막 행

minimums 2023. 5. 3. 20:53
반응형

각 ID에 대한 Postgresql 추출 마지막 행

다음 데이터가 있다고 가정합니다.

  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

제가 그걸 어떻게 할 수 있을까요?

가장 효율적인 방법은 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;

대부분의 경우 창 기능이 있는 솔루션은 하위 쿼리를 사용하는 것보다 빠릅니다.

select * 
from bar 
where (id,date) in (select id,max(date) from bar group by id)

Postgre에서 테스트됨SQL, MySQL

저는 이것이 가장 빠른 해결책이라고 생각했습니다.

 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

대부분의 시나리오에서 가장 효율적인 방법은GROUP BY

저는 다음을 사용하는 것을 결정하는 승인된 답변을 보았습니다.distinct on (id) id문제를 푸는 가장 효율적인 방법은 질문에 기술된 문제를 해결하는 것이지만 저는 그것이 매우 정확하지 않다고 생각합니다.안타깝게도 저는 POSTGRES doc'에서 도움이 되는 통찰력을 찾을 수 없었지만 다른 것을 거의 언급하지 않고 예시를 제공하는 이 기사를 찾았습니다.

그룹화 기준 접근 방식은 확실히 성능 향상으로 이어집니다.


우리는 직장에서 이 주제에 대해 논의했고 4,114,692개 행의 태그 깜박임에 대한 일부 데이터를 보관하고 tag_id 및 타임스탬프(분리된 인덱스)에 대한 인덱스를 가진 테이블에 대해 약간의 경험을 했습니다.

다음은 쿼리입니다.

1. 구분 사용:

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

2. CTE + 그룹화 기준 + 가입:

`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 ms(00:01.656)와 16723.346 ms(00:16.723)의 10배(!) 빠른 속도를 보여주며, 물론 동일한 데이터를 제공합니다.

id별로 그룹화하고 집계 함수를 사용하여 마지막 레코드의 기준을 충족합니다.예를들면

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

언급URL : https://stackoverflow.com/questions/28085468/postgresql-extract-last-row-for-each-id

반응형