Sottoquery correlata Oracle nell'elenco DA
Domanda
Ho appena provato a eseguire una sottoquery correlata nella clausola FROM
di un'istruzione SELECT
in Oracle, ma mi è stato mostrato un errore che indicava che non potevo fare il correlazione (qualcosa per l'effetto che Obs.pID
non è stato riconosciuto).
Dovrebbe funzionare?
FROM ml.Person Person
JOIN ml.Obs ON Person.pID = Obs.pId
JOIN (SELECT ObsMax2.pId, ObsMax2.hdId
, MAX(ObsMax2.obsDate) as maxDate
FROM ml.Obs ObsMax2
WHERE ObsMax2.pId = Obs.pId
AND ObsMax2.obsDate < {?EndDate}
GROUP BY ObsMax2.pId, ObsMax2.hdId) ObsMax
ON Obs.pId = ObsMax.pId
AND Obs.hdId = ObsMax.hdId
AND Obs.obsDate = ObsMax.maxDate
La mia soluzione alternativa sembra essere quella di renderlo una sottoquery non correlata e aggiungere criteri alla sottoquery che gli impediscono di funzionare completamente tra, stupore, stupore, oof Spiacente.
Preferirei capire come correlarlo correttamente, sebbene, se possibile, la vista che funziona come quella subquery impiega un'eternità a essere costruita.
Soluzione
Puoi raggiungere l'intento di questa parte della query usando una funzione analitica per identificare il obsdate massimo per ogni pid e hdid.
Sarebbe qualcosa del tipo:
select ...
from (
SELECT pId,
hdId,
obsDate
MAX(obsDate) over (partition by pId, hdId) maxDate
FROM ml.Obs
WHERE obsDate < {?EndDate}
)
where obsDate = maxDate
/
Altri suggerimenti
Le query secondarie all'interno di una clausola FROM non possono fare riferimento ad altre tabelle della stessa clausola FROM. La rimozione della clausola ObsMax2.pId = Obs.pId dovrebbe risolvere il problema e da quello che posso sapere ti darà esattamente lo stesso risultato poiché la stessa clausola è nella condizione di join. Tuttavia, come accennato, potresti riscontrare problemi di prestazioni con il GROUP BY nella sottoquery.
Da quello che posso dire, stai cercando di ottenere i singoli record pID / hdId da ml.Obs con il più grande obsDate che è inferiore a {EndDate}. In tal caso, che dire di spostare la sottoquery nella clausola WHERE dove è possibile correlarla? Per esempio:.
select ...
from
ml.Person Person
join ml.Obs on Person.PID = Obs.pId
where Obs.obsDate = (
select max(obsDate)
from ml.Obs Obs2
where Obs2.pId = Obs.pId
and obs2.hdId = Obs.hdId
and Obs2.obsDate < {EndDate})
Hai aggiunto il prefisso a molte delle tue tabelle con " ml. " ma non ovunque (il primo join, ad esempio). Supponendo che sia necessario (per utente / autorizzazioni / qualunque cosa):
ISCRIVITI ml.Obs ON Person.pID = ** ml. ** Obs.pId
o
ISCRIVITI ml.Obs Obs ON Person.pID = Obs.pId
Ci sono altri posti dove sarebbe necessario anche questo.
In caso contrario, rimuoverli dalla query perché sono irrilevanti e distraenti.