質問

私は私の最近十分に更新されていないテーブル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;

これは効果的に選択し、他の句の両方で使用することができる変数を定義することができます。

サブクエリが必ずしも適切に参照されるテーブルの列への結合を可能にしない、しかし、OUTERを行い適用

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

<のhref = "https://smehrozalam.wordpress.com/2010/01/25/referring-computedcalculated-columns-in-the-where-and-group-by-clause/" のrelへの賞賛=」 noreferrer nofollowを ">サイードMehrozアラムはします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top