IT

Oracle: 그룹의 가치를 극대화할 수 있습니까?

itgroup 2023. 10. 5. 21:31
반응형

Oracle: 그룹의 가치를 극대화할 수 있습니까?

이와 같은 표가 주어졌을 때 각 모니터에 대한 가장 최근의 보정 정보는 무엇입니까?즉, 각 모니터의 최대 날짜 값을 찾고 싶습니다.오라클 고유의 기능은 제 애플리케이션에 적합합니다.

monitor_id     calibration_date  value
----------     ----------------  -----
1              2011/10/22        15
1              2012/01/01        16
1              2012/01/20        17
2              2011/10/22        18
2              2012/01/02        19

이 예제의 결과는 다음과 같습니다.

1  2012/01/20 17
2  2012/01/02 19

분석적인 기능을 사용하는 편입니다.

SELECT monitor_id,
       host_name,
       calibration_date,
       value
  FROM (SELECT b.monitor_id,
               b.host_name,
               a.calibration_date,
               a.value,
               rank() over (partition by b.monitor_id order by a.calibration_date desc) rnk
          FROM table_name a,
               table_name2 b
         WHERE a.some_key = b.some_key)
 WHERE rnk = 1

상관 관계가 있는 하위 쿼리를 사용할 수도 있지만 효율성이 떨어집니다.

SELECT monitor_id,
       calibration_date,
       value
  FROM table_name a
 WHERE a.calibration_date = (SELECT MAX(b.calibration_date)
                               FROM table_name b
                              WHERE a.monitor_id = b.monitor_id)

개인적으로 선호하는 것은 다음과 같습니다.

SELECT DISTINCT
       monitor_id
      ,MAX(calibration_date)
       OVER (PARTITION BY monitor_id)
       AS latest_calibration_date
      ,FIRST_VALUE(value)
       OVER (PARTITION BY monitor_id
             ORDER BY calibration_date DESC)
       AS latest_value
FROM mytable;

변형은 다음을 사용하는 것입니다.FIRST_VALUE의 구문latest_calibration_date뿐만 아니라.어느 쪽이든 효과가 있습니다.

윈도우 함수 솔루션은 가장 효율적이어야 하며 테이블 또는 인덱스 스캔 하나만 수행해야 합니다.제가 여기에 올리는 것은 직관적이고 이해하기 쉽다는 점에서 점수를 얻는다고 생각합니다.SQL 서버에서 테스트해보니 2차 윈도우 기능을 수행하여 2개의 인덱스 스캔 결과가 나왔습니다.

SELECT T1.monitor_id, T1.calibration_date, T1.value
FROM someTable AS T1
WHERE NOT EXISTS 
(
    SELECT * 
    FROM someTable AS T2
    WHERE T2.monitor_id = T1.monitor_id AND T2.value > T1.value
)
 GROUP BY T1.monitor_id, T1.calibration_date, T1.value

그리고 대부분의 경우, 성능은 동일하지만(63% 비용 대비 37%) 성능은 더 낮습니다(sql 서버의 경우에도 마찬가지).실행 계획에서 왼쪽 외부 조인을 사용하는 반면 첫 번째 조인에서는 안티 세미 머지 조인을 사용합니다.

SELECT T1.monitor_id, T1.calibration_date, T1.value
FROM someTable AS T1
LEFT JOIN someTable AS T2 ON T2.monitor_id = T1.monitor_id AND T2.value > T1.value
WHERE T2.monitor_id IS NULL
GROUP BY T1.monitor_id, T1.calibration_date, T1.value
select monitor_id, calibration_date, value 
from table
where calibration_date in(
  select max(calibration_date) as calibration_date 
  from table
  group by monitor_id
  )

언급URL : https://stackoverflow.com/questions/9220944/oracle-getting-maximum-value-of-a-group

반응형