A Oracle correlacionados subconsulta na lista FROM
Pergunta
Eu apenas tentei fazer uma subconsulta correlacionada na cláusula FROM
de uma declaração SELECT
em Oracle, mas eu estava determinado um erro indicando que eu não poderia fazer a correlação (algo no sentido de que Obs.pID
não foi reconhecido).
Se este trabalho?
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
Minha solução parece ser para torná-lo uma subconsulta não correlacionada, e adicionar critérios para a subconsulta que o impede de funcionar completamente amuck, amuck, amu - oof Sorry.
Eu prefiro descobrir como correlacioná-la corretamente, porém, se possível -. A visão de que obras como essa subconsulta leva uma eternidade para construção
Solução
Você pode conseguir a intenção desta parte da consulta usando uma função analítica para identificar o obsDate máximo para cada pid e hdid.
Seria algo como:
select ...
from (
SELECT pId,
hdId,
obsDate
MAX(obsDate) over (partition by pId, hdId) maxDate
FROM ml.Obs
WHERE obsDate < {?EndDate}
)
where obsDate = maxDate
/
Outras dicas
Sub-consultas dentro de uma cláusula FROM não pode se referir a outras tabelas a partir da mesma cláusula FROM. Removendo o ObsMax2.pId = Obs.pId cláusula deve resolver o problema e para que eu possa dizer-lhe dará exatamente o mesmo resultado desde a mesma cláusula está na condição de junção. No entanto, como você menciona, você pode executar em problemas de desempenho com ter a GROUP BY na sub-consulta.
Do que eu posso dizer, você está tentando obter os registros individuais PID / hdId de ml.Obs com o maior obsDate que é menos de {EndDate}. Nesse caso, o que dizer de mover o sub-consulta na cláusula WHERE, onde pode correlacioná-la? Por exemplo:.
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})
Você prefixado muitas das suas tabelas com "ml". mas não em todos os lugares (o primeiro unir-se, por exemplo). Supondo que você precisa que (para o usuário / permissões / whatever):
Cadastre ml.Obs ON Person.pID = ** ml. ** Obs.pId
ou
Cadastre ml.Obs Obs ON Person.pID = Obs.pId
Há outros lugares onde isso seriam necessários também.
Se isto não for o caso, removê-los da sua consulta, porque eles são irrelevantes e distraindo.