sql >> Database >  >> RDS >> Oracle

Ongeldige ID in dubbel geneste zoekopdracht met ORDER BY en ROWNUM

In de scalaire subquery die u gebruikt, kunt u alleen verwijzen naar de tabellen van de "hoofd"-query "één genest niveau naar beneden", niet verder naar beneden, zoals u hebt gezien. (Ik geloof dat deze beperking in versie 12 is opgeheven, dus misschien kun je je database gewoon upgraden?;-)

In de scalaire subquery probeert u de waarde van de INSERTDATE-kolom van de eerste rij te krijgen volgens uw bestelling. Dat kan ook als volgt worden geschreven zonder te nesten:

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 vertelt de MAX-functie dat deze de MAX alleen moet berekenen van die rijen die eerst rangschikken in de ORDER BY-clausule. Dus als uw ORDER BY "uniek" is, wordt MAX alleen toegepast op één rij. Als uw ORDER BY niet "uniek" is en duplicaten kan hebben, kunt u overwegen of u de MAX of de MIN wilt (of iets toevoegen aan de ORDER BY om het uniek te maken.)

(Als u Oracle versie 12 had gebruikt, zou een alternatief voor de KEEP (DENSE_RANK-truc zou zijn om de FIRST 1 ROW ONLY-clausule van de SELECT-instructie te gebruiken.)




  1. MySQL Workbench wordt opgehaald... -- kan niet door DB bladeren

  2. PHP detecteert poging tot SQL-injectie

  3. kunnen we welsprekend voorkomen in een groot aantal records?

  4. SQL neemt alleen de numerieke waarden van een varchar