Frage

Ich habe eine Abfrage, die ist gemeint, um zu zeigen, mir alle Zeilen in Tabelle A, die nicht aktualisiert wurden vor kurzem genug.(Jede Zeile sollte aktualisiert werden innerhalb von 2 Monaten nach "month_no".):

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

Die Letzte Zeile in der WHERE-Klausel bewirkt, dass ein "ORA-00904 Ungültiger Bezeichner" error.Unnötig zu sagen, ich will nicht, wiederholen Sie den gesamten DECODE-Funktion in meiner WHERE-Klausel.Irgendwelche Gedanken?(Beide fixes und workarounds akzeptiert...)

War es hilfreich?

Lösung

Dies ist direkt nicht möglich, da in chronologischer Reihenfolge, WHERE geschieht vor SELECT, der immer der letzte Schritt in der Ausführung Kette ist.

Sie können eine Unterauswahl tun und Filter auf sie:

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

Interessante paar Informationen aus den Kommentaren nach oben verschoben:

  

Es sollte keine Leistungseinbußen sein.   Oracle muss nicht materialisieren   Innen Abfragen vor dem Anwenden äußeren   Bedingungen - Oracle wird prüfen   Transformieren dieser Abfrage intern und   schiebt das Prädikat nach unten in die Innen   abfragen und wird dies tun, wenn es kostet   Wirksam. - Justin Cave

Andere Tipps

 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

Oder Sie können Ihren alias in einem HAVING Klausel

So wie ein alternativer Ansatz für Sie tun kann:

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

Sie können auch eine permanente Ansicht für Ihre Warteschlange erstellen und aus Sicht auswählen.

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

Es ist möglich, effektiv eine Variable zu definieren, die sowohl in der SELECT, WHERE und anderen Klauseln verwendet werden können.

Eine Unterabfrage nicht unbedingt für geeignete erlaubt Bindung an die referenzierten Tabellenspalten jedoch OUTER Gegenstandslos.

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

Ein großes Lob an Syed Mehroz Alam .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top