sql >> Databáze >  >> RDS >> Oracle

Neplatný identifikátor ve dvojitě vnořeném dotazu s ORDER BY a ROWNUM

Ve skalárním poddotazu, který používáte, můžete odkazovat pouze na tabulky z „hlavního“ dotazu „o jednu vnořenou úroveň níže“, nikoli dále dolů, jak jste viděli. (Domnívám se, že toto omezení je ve verzi 12 zrušeno, takže možná můžete svou databázi upgradovat?;-)

Ve skalárním poddotazu se snažíte získat hodnotu sloupce INSERTDATE prvního řádku podle vaší objednávky. To lze také zapsat bez vnoření následovně:

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 říká funkci MAX, že by měla vypočítat MAX pouze z těch řádků, které jsou první v doložce ORDER BY. Pokud je tedy vaše ORDER BY „unikátní“, MAX se použije pouze na jednoho řádek. Pokud vaše ORDER BY není "unikátní" a může mít duplikáty, můžete se zamyslet nad tím, zda chcete MAX nebo MIN (nebo přidat něco do ORDER BY, aby byla jedinečná.)

(Pokud jste používali Oracle verze 12, alternativa k KEEP (trik DENSE_RANK by spočíval v použití klauzule FIRST 1 ROW ONLY příkazu SELECT.)




  1. Testování DbUnit MySQL Java

  2. Jak získám informace o datu/čase ze sloupce TIMESTAMP?

  3. Jak vytvoříte dočasnou tabulku v databázi Oracle?

  4. Jak vložit více řádků z textové oblasti v MySQL