programing

오라클에서 각 그룹에 대한 최신 행 선택

magicmemo 2023. 7. 20. 21:50
반응형

오라클에서 각 그룹에 대한 최신 행 선택

방명록에 사용자 의견이 있는 테이블이 있습니다.열은 id, user_id, 제목, 주석, 타임스탬프입니다.

각 사용자에 대한 최신 행을 선택해야 합니다.group by를 사용하여 이 작업을 수행하려고 했지만 user_id로 그룹화하는 동일한 쿼리에서 다른 항목을 선택할 수 없기 때문에 관리하지 못했습니다.

SELECT user_id, MAX(ts) FROM comments GROUP BY user_id

예를 들어 이 쿼리에서는 열 ID, 기울기 및 주석을 선택하는 데 추가할 수 없습니다.이것이 어떻게 행해지는가?

분석 기능을 사용할 수 있습니다.

SELECT *
  FROM (SELECT c.*,
               rank() over (partition by user_id order by ts desc) rnk
          FROM comments c)
 WHERE rnk = 1

동점 처리 방법에 따라(동일한 행이 두 개일 수 있는 경우)user_id그리고.ts), 사용할 수 있습니다.row_number또는dense_rank보다 기능적인rank.rank동점인 경우 여러 행을 먼저 지정할 수 있습니다.row_number동점일 경우 임의로 한 줄을 반환합니다.dense_rank처럼 행동할 것입니다.rank첫 번째로 동점이 되었지만 두 행이 첫 번째로 동점이라고 가정할 때 세 번째가 아닌 두 번째 행으로 간주되는 행의 경우.

다음을 사용하여 쿼리를 작성할 수 있습니다.JOIN:

select c.*
from comments c join
     (select user_id, max(ts) as maxts
      from comments c2
      group by user_id
     ) cc
     on c.user_id = cc.user_id and c.ts = cc.maxts;

다른 방법도 있습니다.일반적인 조언은 다음과 같습니다.row_number():

select t.*
from (select c.*, row_number() over (partition by user_id order by ts desc) as seqnum
      from comments c
     ) c
where seqnum = 1;

이 두 쿼리는 미묘하게 다릅니다.첫 번째 사용자는 사용자에 대한 최근 주석이 정확히 같은 경우 중복 항목을 반환합니다.ts두 번째는 사용자당 하나의 행을 반환합니다.

이러한 유형의 문제는 매우 간단하고 효율적인 해결책을 가지고 있습니다.dense rank first/last함수:

select id,
       max(user_id) keep (dense_rank last order by ts) over (partition by id) as user_id,
       max(title)   keep (dense_rank last order by ts) over (partition by id) as title,
       max(comment) keep (dense_rank last order by ts) over (partition by id) as comment,
       max(ts)                                                                as ts
from   comments;

언급URL : https://stackoverflow.com/questions/40404497/select-latest-row-for-each-group-from-oracle

반응형