source

하위 쿼리 문제별 Oracle SQL 순서 지정!

ittop 2023. 6. 26. 23:10
반응형

하위 쿼리 문제별 Oracle SQL 순서 지정!

Oracle SQL에서 하위 쿼리를 실행하려고 하는데 하위 쿼리 열을 주문할 수 없습니다.Oracle은 반환된 열 중 주 쿼리로 돌아갈 열을 마음대로 선택하는 것처럼 보이기 때문에 하위 쿼리를 정렬하는 것이 중요합니다.

select ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state,
        (select last_updated from mwcrm.process_state_transition subpst
            where subpst.last_updated > pst.last_updated
            and subpst.process_state = ps.id
            and rownum = 1) as next_response
        from mwcrm.process_state ps, mwcrm.process_state_transition pst
        where ps.created_date > sysdate - 1/24
        and ps.id=pst.process_state
        order by ps.id asc

다음과 같이 해야 합니다.

select ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state,
        (select last_updated from mwcrm.process_state_transition subpst
            where subpst.last_updated > pst.last_updated
            and subpst.process_state = ps.id
            and rownum = 1
            order by subpst.last_updated asc) as next_response
        from mwcrm.process_state ps, mwcrm.process_state_transition pst
        where ps.created_date > sysdate - 1/24
        and ps.id=pst.process_state
        order by ps.id asc

dcw와 Dems 모두 적절한 대체 쿼리를 제공했습니다.저는 단지 당신의 질문이 왜 당신이 예상했던 것처럼 작동하지 않는지에 대한 설명을 하고 싶습니다.

ROWNUM과 ORDER BY가 포함된 조회가 있는 경우 Oracle은 ROWNUM을 먼저 적용한 다음 ORDER BY를 적용합니다.그래서 질문은

SELECT *
  FROM emp
 WHERE rownum <= 5
 ORDER BY empno

에서 임의의 5개 행을 가져옵니다.EMP표를 만들고 분류합니다. 거의 확실히 의도된 것이 아닙니다.ROWNUM을 사용하여 "첫 번째 N" 행을 가져오려면 쿼리를 중첩해야 합니다.이 쿼리

SELECT *
  FROM (SELECT *
          FROM emp
         ORDER BY empno)
 WHERE rownum <= 5

EMP 테이블의 행을 정렬하고 처음 5를 반환합니다.

실제로 "주문"은 가장 바깥쪽 쿼리에서만 의미가 있습니다. 하위 쿼리에서 주문하면 외부 쿼리는 결과를 마음대로 스크램블할 수 있으므로 하위 쿼리 순서는 기본적으로 아무 것도 하지 않습니다.

pst.last_update보다 큰 최소 last_update를 원하는 것처럼 보입니다. 첫 번째 행(next_response에 대해 두 행이 묶여 있는 경우와 같은 다른 문제가 발생함)보다는 최소(집계)로 보는 것이 더 쉽습니다.

한 번 해보세요.공정한 경고입니다. 오라클을 앞에 둔 지 몇 년이 지났고, 저는 열에 대한 하위 쿼리 구문에 익숙하지 않습니다. 만약 이것이 터지면 from 절에 있는 버전을 만들 것입니다.

select
    ps.id, ps.created_date, pst.last_updated, pst.from_state, pst.to_state,
    (   select min(last_updated)
        from mwcrm.process_state_transition subpst
        where subpst.last_updated > pst.last_updated
          and subpst.process_state = ps.id) as next_response
from <the rest>

제가 직접 경험한 일인데, 당신은 rownum 대신 ROW_NUMBER()와 추가 수준의 하위 쿼리를 사용해야 합니다...

새로운 서브쿼리를 보여주는 것은...

(
  SELECT
    last_updated
  FROM
  (
    select
      last_updated,
      ROW_NUMBER() OVER (ORDER BY last_updated ASC) row_id
    from
      mwcrm.process_state_transition subpst
    where
      subpst.last_updated > pst.last_updated
      and subpst.process_state = ps.id
  )
    as ordered_results
  WHERE
    row_id = 1
)
  as next_response


대신 MIN을 사용할 수도 있습니다.

(
  select
    MIN(last_updated)
  from
    mwcrm.process_state_transition subpst
  where
    subpst.last_updated > pst.last_updated
    and subpst.process_state = ps.id
)
  as next_response

확인된 답은 명백하게 틀렸습니다.고유한 행 인덱스 번호를 생성하는 하위 쿼리를 고려합니다.예를들면ROWNUM오라클에서.

페이징 목적으로 고유한 레코드 번호를 만들려면 하위 쿼리가 필요합니다(아래 참조).

다음 쿼리 예제를 생각해 보십시오.

SELECT T0.*, T1.* FROM T0 LEFT JOIN T1 ON T0.Id = T1.Id
JOIN 
(
SELECT DISTINCT T0.*, ROWNUM FROM T0 LEFT JOIN T1 ON T0.Id = T1.Id
WHERE (filter...)
)
WHERE (filter...) AND (ROWNUM > 10 AND ROWNUM < 20)
ORDER BY T1.Name DESC

내부 쿼리는 정확히 동일한 쿼리이지만DISTINCT요. T0을 안 요. 당신은 그것을 넣을 수 없습니다.ROWNUM그 이후로 외부 질문에.LEFT JOIN더 많은 결과를 생성할 수 있습니다.

이 내부 쿼리를주문할 수 (만약당신내수있다면주할문의를부질이▁(▁if▁the있면▁(다)T1.Name DESC된 성된생ROWNUM내부 쿼리에서 일치합니다.를 할 수 에.ORDER B하위 쿼리의 Y는 숫자가 일치하지 않으며 사용할 수 없습니다.

께 .ROW_NUMBER OVER (ORDER BY ...)이 문제를 해결합니다.모든 DB 엔진에서 지원되는 것은 아닙니다.

방법 중 인 두가지방중하나는법▁one.LIMIT)ORDER및 ) 및그ROW_NUMBER() OVER대부분의 DB 엔진에 적용됩니다.하지만 이러한 옵션 중 하나가 없다면, 예를 들어.ROWNUM그렇다면 당신의 유일한 선택입니다.ORDER BY서브쿼리는 필수입니다!

언급URL : https://stackoverflow.com/questions/5119190/oracle-sql-order-by-in-subquery-problems

반응형