2008-12-10 10 views
59

Ich habe eine Abfrage, die mir Zeilen in Tabelle A zeigen soll, die nicht genug kürzlich aktualisiert wurden. (Jede Zeile soll nach "month_no" innerhalb von 2 Monaten aktualisiert werden.):Verwendung eines Alias ​​in einer WHERE-Klausel

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 verursacht einen "ORA-00904 Ungültige Identifier" Fehler. Es ist unnötig zu sagen, dass ich nicht die gesamte DECODE-Funktion in meiner WHERE-Klausel wiederholen möchte. Irgendwelche Gedanken? (Beide Fixes und Umgehungen akzeptiert ...)

Antwort

100

Dies ist nicht direkt möglich, da chronologisch, wo vor SELECT, die immer der letzte Schritt in der Ausführungskette ist.

Sie können auf eine Unterauswahl und Filter tun:

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 bisschen info bewegt von den Kommentaren auf:

Es sollte keine Leistungseinbußen sein. Oracle braucht nicht innere Anfragen materialisieren vor äußeren Bedingungen Anwendung - Oracle Transformation diese intern Abfrage prüfen wird und das Prädikat nach unten in die inneren Abfrage drücken und so tun, wenn es kosteneffektiv ist. - Justin Cave

9

Oder Sie können Ihr Alias ​​in einer HAVING Klausel

+4

Dies wäre ein interessanter Ansatz, können Sie einen Code geben? – rob5408

+0

die gleiche Regel, wo gilt, so ist dies keine Lösung. – Alexey

+0

Ich bin auf MySQL (5.5) fest, weiß nicht, ob dies für Oracle gilt. ABER: 'SELECT CONCAT (Namen, Nachname) AS x VON Kunden mit X WIE '% a%'' funktioniert, während 'SELECT CONCAT (Namen, Nachname) AS x VON Kunden WHERE x wie '% a%' 'scheitert (" Unbekannte Spalte 'x' in 'where-Klausel' ") – fr13d

12
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 
1

Genau wie ein alternativer Ansatz für Sie tun können:

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 erstellen für Ihre Warteschlange und wählen Sie aus der Ansicht.

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