it-swarm.com.de

Verwenden eines Alias ​​in einer WHERE-Klausel

Ich habe eine Abfrage, die mir Zeilen in Tabelle A anzeigen soll, die in letzter Zeit nicht genug aktualisiert wurden. (Jede Zeile sollte innerhalb von 2 Monaten nach "month_no" aktualisiert werden.):

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 Fehler "ORA-00904 Invalid Identifier". Unnötig zu sagen, ich möchte nicht die gesamte DECODE-Funktion in meiner WHERE-Klausel wiederholen. Irgendwelche Gedanken? (Sowohl Fixes als auch Workarounds werden akzeptiert ...)

64
JPLemme

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

Sie können eine Unterauswahl vornehmen und darauf filtern:

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 Informationen stiegen von den Kommentaren auf:

Es sollte keine Leistungseinbußen geben . Oracle muss nicht verwirklicht werden innere Abfragen vor dem Anwenden von äußerem Bedingungen - Oracle berücksichtigt diese Abfrage intern umwandeln und Drücken Sie das Prädikat in das Innere Abfrage und wird dies tun, wenn es kostet Wirksam. - Justin Cave

107
Tomalak
 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
12
me_an

Oder Sie haben Ihren Alias ​​in einer HAVING-Klausel

9
James

Als Alternative dazu können Sie Folgendes tun:

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 der Ansicht auswählen.

CREATE OR REPLACE VIEW_1 AS (SELECT ...);
SELECT * FROM VIEW_1;
2
J-Alex

Es ist möglich, eine Variable effektiv zu definieren, die in den Klauseln SELECT, WHERE und anderen verwendet werden kann.

Eine Unterabfrage lässt nicht notwendigerweise eine geeignete Bindung an die referenzierten Tabellenspalten zu, jedoch 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

Kudos an Syed Mehroz Alam .

0
Peter Aylett