Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Ungültiger Bezeichner in doppelt verschachtelter Abfrage mit ORDER BY und ROWNUM

In der von Ihnen verwendeten skalaren Unterabfrage können Sie nur die Tabellen aus der "Haupt" -Abfrage "eine verschachtelte Ebene nach unten" referenzieren, nicht weiter unten, wie Sie gesehen haben. (Ich glaube, diese Einschränkung wird in Version 12 aufgehoben, also können Sie vielleicht einfach Ihre Datenbank aktualisieren?;-)

In der skalaren Unterabfrage versuchen Sie, den Wert der INSERTDATE-Spalte der ersten Zeile gemäß Ihrer Reihenfolge zu erhalten. Das kann auch ohne Verschachtelung wie folgt geschrieben werden:

SELECT
O.INSERTDATE OrderCreateDate,

-- Determine delivery date
(SELECT MAX(DD.INSERTDATE) KEEP (
          DENSE_RANK FIRST ORDER BY
          DD.CLOSED ASC, ABS(TRUNC(CURRENT_DATE-TO_DATE(TO_CHAR(DD.INSERTDATE, 'DDMMYYYY'), 'DDMMYYYY'))) ASC
        )
   FROM MY_DELIVERYDATE_TABLE DD
   JOIN MY_ORDERPOS_TABLE OP2 ON DD.FK_ORDERPOS=OP2.ID
   LEFT OUTER JOIN MY_ORDER_TABLE O2 ON OP2.FK_ORDER=O2.ID
   WHERE OP2.FK_ORDER=O.ID AND -- This will no longer give "Invalid identifier O.ID"
         DD.DELFLAG IS NULL AND OP2.DELFLAG IS NULL
) DeliveryDate

FROM MY_ORDER_TABLE O
WHERE O.ID = 620; -- ID goes here!

KEEP (DENSE_RANK FIRST) teilt der MAX-Funktion mit, dass sie nur den MAX berechnen soll der Zeilen, die erste rangieren in der ORDER BY-Klausel. Wenn Ihr ORDER BY also "einzigartig" ist, wird MAX nur auf einen angewendet die Zeile. Wenn Ihr ORDER BY nicht "eindeutig" ist und Duplikate haben kann, sollten Sie darüber nachdenken, ob Sie das MAX oder das MIN wollen (oder etwas zu ORDER BY hinzufügen, um es eindeutig zu machen.)

(Wenn Sie Oracle Version 12 verwendet hätten, wäre eine Alternative zum KEEP (DENSE_RANK-Trick, die FIRST 1 ROW ONLY-Klausel der SELECT-Anweisung zu verwenden.)