Oracle correlacionó la subconsulta en la lista DE
Pregunta
Acabo de intentar hacer una subconsulta correlacionada en la cláusula FROM
de una declaración de SELECT
en Oracle, pero recibí un error que indicaba que no podía hacer la correlación (algo en el sentido de que Obs.pID
no fue reconocido).
¿Esto debería funcionar?
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
Parece que mi solución alternativa es convertirla en una subconsulta no correlacionada, y agregar criterios a la subconsulta que evite que se ejecute completamente amuck, amuck, amu-- oof Sorry.
Prefiero averiguar cómo correlacionarlo correctamente, aunque, si es posible, la vista que funciona como esa subconsulta tarda mucho en construirse.
Solución
Puede lograr el propósito de esta parte de la consulta mediante el uso de una función analítica para identificar el máximo de obsidate para cada pid y hdid.
Sería algo así como:
select ...
from (
SELECT pId,
hdId,
obsDate
MAX(obsDate) over (partition by pId, hdId) maxDate
FROM ml.Obs
WHERE obsDate < {?EndDate}
)
where obsDate = maxDate
/
Otros consejos
Las subconsultas dentro de una cláusula FROM no pueden referirse a otras tablas de la misma cláusula FROM. La eliminación de la cláusula ObsMax2.pId = Obs.pId debería resolver el problema y, por lo que sé, le dará exactamente el mismo resultado, ya que la misma cláusula está en la condición de unión. Sin embargo, como mencionó, puede tener problemas de rendimiento al tener la opción GROUP BY en la subconsulta.
Por lo que puedo decir, está intentando obtener los registros individuales pID / hdId de ml.Obs con la mayor obsDate que es menor que {EndDate}. En ese caso, ¿qué hay de mover la subconsulta en la cláusula WHERE donde puede correlacionarla? Por ejemplo:
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})
Ha prefijado muchas de sus tablas con " ml. " pero no en todas partes (la primera unión, por ejemplo). Suponiendo que lo necesite (para usuario / permisos / lo que sea):
ÚNETE a ml.Obs ON Person.pID = ** ml. ** Obs.pId
o
ÚNETE a ml.Obs Obs ON Person.pID = Obs.pId
Hay otros lugares donde esto también sería necesario.
Si este no es el caso, elimínalos de tu consulta porque son irrelevantes y distraen.