Program Tip

WHERE 절에서 별칭 사용

programtip 2020. 11. 20. 09:28
반응형

WHERE 절에서 별칭 사용


최근에 업데이트되지 않은 테이블 A의 행을 표시하기위한 쿼리가 있습니다. (각 행은 "month_no"이후 2 개월 이내에 업데이트되어야합니다.) :

SELECT A.identifier
     , A.name
     , TO_NUMBER(DECODE( A.month_no
             , 1, 200803 
             , 2, 200804 
             , 3, 200805 
             , 4, 200806 
             , 5, 200807 
             , 6, 200808 
             , 7, 200809 
             , 8, 200810 
             , 9, 200811 
             , 10, 200812 
             , 11, 200701 
             , 12, 200702
             , NULL)) as MONTH_NO
     , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
  FROM table_a A
     , table_b B
 WHERE A.identifier = B.identifier
   AND MONTH_NO > UPD_DATE

WHERE 절의 마지막 줄은 "ORA-00904 잘못된 식별자"오류를 발생시킵니다. 말할 필요도없이 WHERE 절에서 전체 DECODE 함수를 반복하고 싶지 않습니다. 이견있는 사람? (수정 및 해결 방법 모두 허용됨 ...)


시간순으로 WHERE가 SELECT 이전에 발생 하기 때문에 이는 직접적으로 불가능합니다 . 이는 항상 실행 체인의 마지막 단계입니다.

하위 선택을 수행하고이를 필터링 할 수 있습니다.

SELECT * FROM
(
  SELECT A.identifier
    , A.name
    , TO_NUMBER(DECODE( A.month_no
      , 1, 200803 
      , 2, 200804 
      , 3, 200805 
      , 4, 200806 
      , 5, 200807 
      , 6, 200808 
      , 7, 200809 
      , 8, 200810 
      , 9, 200811 
      , 10, 200812 
      , 11, 200701 
      , 12, 200702
      , NULL)) as MONTH_NO
    , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
  FROM table_a A
    , table_b B
  WHERE A.identifier = B.identifier
) AS inner_table
WHERE 
  MONTH_NO > UPD_DATE

댓글에서 흥미로운 정보가 올라갔습니다.

성능 저하가 없어야합니다. Oracle은 외부 조건을 적용하기 전에 내부 쿼리를 구체화 할 필요가 없습니다. Oracle은이 쿼리를 내부적으로 변환하는 것을 고려하고 조건자를 내부 쿼리로 푸시하고 비용 효율적인 경우 그렇게 할 것입니다. 저스틴 케이브


 SELECT A.identifier
 , A.name
 , TO_NUMBER(DECODE( A.month_no
         , 1, 200803 
         , 2, 200804 
         , 3, 200805 
         , 4, 200806 
         , 5, 200807 
         , 6, 200808 
         , 7, 200809 
         , 8, 200810 
         , 9, 200811 
         , 10, 200812 
         , 11, 200701 
         , 12, 200702
         , NULL)) as MONTH_NO
 , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
FROM table_a A, table_b B
WHERE .identifier = B.identifier
HAVING MONTH_NO > UPD_DATE

또는 HAVING절에 별칭을 사용할 수 있습니다.


다른 방법으로 다음을 수행 할 수 있습니다.

WITH inner_table AS
(SELECT A.identifier
    , A.name
    , TO_NUMBER(DECODE( A.month_no
      , 1, 200803 
      , 2, 200804 
      , 3, 200805 
      , 4, 200806 
      , 5, 200807 
      , 6, 200808 
      , 7, 200809 
      , 8, 200810 
      , 9, 200811 
      , 10, 200812 
      , 11, 200701 
      , 12, 200702
      , NULL)) as MONTH_NO
    , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
  FROM table_a A
    , table_b B
  WHERE A.identifier = B.identifier)

    SELECT * FROM inner_table 
    WHERE MONTH_NO > UPD_DATE

또한 대기열에 대한 영구보기를 만들고보기에서 선택할 수 있습니다.

CREATE OR REPLACE VIEW_1 AS (SELECT ...);
SELECT * FROM VIEW_1;

SELECT, WHERE 및 기타 절 모두에서 사용할 수있는 변수를 효과적으로 정의 할 수 있습니다.

하위 쿼리는 참조 된 테이블 열에 대한 적절한 바인딩을 반드시 허용하지는 않지만 OUTER APPLY는 허용합니다.

SELECT A.identifier
     , A.name
     , vars.MONTH_NO
     , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
FROM table_a A
     , table_b B ON A.identifier = B.identifier
OUTER APPLY (
   SELECT
        -- variables
        MONTH_NO = TO_NUMBER(DECODE( A.month_no
                     , 1, 200803 
                     , 2, 200804 
                     , 3, 200805 
                     , 4, 200806 
                     , 5, 200807 
                     , 6, 200808 
                     , 7, 200809 
                     , 8, 200810 
                     , 9, 200811 
                     , 10, 200812 
                     , 11, 200701 
                     , 12, 200702
                     , NULL))
) vars
WHERE vars.MONTH_NO > UPD_DATE

Syed Mehroz Alam에 대한 명성 .

참고URL : https://stackoverflow.com/questions/356675/using-an-alias-in-a-where-clause

반응형