Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Identificador inválido na consulta aninhada dupla com ORDER BY e ROWNUM


Na subconsulta escalar que você está usando, você só pode referenciar as tabelas da consulta "principal" "um nível aninhado abaixo", não mais abaixo, como você viu. (Acredito que essa restrição foi levantada na versão 12, então talvez você possa apenas atualizar seu banco de dados?;-)

Na subconsulta escalar você está tentando obter o valor da coluna INSERTDATE da primeira linha de acordo com sua ordenação. Isso também pode ser escrito sem aninhamento da seguinte forma:
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 informa a função MAX, que ela deve calcular o MAX somente dessas linhas classificadas primeiro na cláusula ORDER BY. Portanto, se seu ORDER BY for "único", MAX será aplicado apenas a um fileira. Se o seu ORDER BY não for "único" e puder ter duplicatas, você pode pensar se deseja o MAX ou o MIN (ou adicionar algo ao ORDER BY para torná-lo único).

(Se você estivesse no Oracle versão 12, uma alternativa ao truque KEEP (DENSE_RANK seria usar a cláusula FIRST 1 ROW ONLY da instrução SELECT).