Oracle korrelierte Unterabfrage in FROM-Liste
Frage
Ich habe gerade versucht, eine korrelierte Unterabfrage in der FROM
Klausel einer SELECT
Anweisung in Oracle zu tun, aber ich war ein Fehler gegeben anzeigt, dass ich nicht die Korrelation tun konnte (etwas zu dem Effekt, dass Obs.pID
nicht erkannt wurde).
Sollte diese Arbeit?
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
Meine Abhilfe scheint zu sein, es ist ein nicht-korrelierten Unterabfrage zu machen, und fügen Sie Kriterien für die Unterabfrage, die sie vom Laufen völlig Amok hält, Amok, amu - oof Es tut uns leid.
Ich würde lieber herausfinden, wie richtig es korreliert, obwohl, wenn möglich -. Die Ansicht, dass, wie die Unterabfrage funktioniert dauert ewig zu bauen
Lösung
Sie können die Absicht dieser Teil der Abfrage erreichen durch eine analytische Funktion unter Verwendung der maximalen obsDate für jeden pid und hdid zu identifizieren.
Es wäre so etwas wie:
select ...
from (
SELECT pId,
hdId,
obsDate
MAX(obsDate) over (partition by pId, hdId) maxDate
FROM ml.Obs
WHERE obsDate < {?EndDate}
)
where obsDate = maxDate
/
Andere Tipps
Unterabfragen innerhalb einer FROM-Klausel kann nicht auf andere Tabellen aus derselben FROM-Klausel verweisen. Entfernen der ObsMax2.pId = Obs.pId Klausel das Problem lösen sollte und ich kann Ihnen genau das gleiche Ergebnis sagen geben, da die gleiche Klausel in der Join-Bedingung ist. Doch wie Sie erwähnen, dass Sie in Performance-Probleme laufen in der Unterabfrage die GROUP BY mit mit.
Von dem, was ich sagen kann, Sie versuchen, die einzelnen pID / hdId Datensätze aus ml.Obs mit dem größten obsDate zu erhalten, das ist weniger als {EndDate}. In diesem Fall, was über die Unterabfrage in der WHERE-Klausel zu bewegen, wo können Sie es korrelieren? Z.
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})
Sie haben viele Ihrer Tabellen mit dem Präfix „ml“. aber nicht überall (die erste beitreten, zum Beispiel). Angenommen, Sie müssen, dass (für Benutzer / Berechtigungen / was auch immer):
JOIN ml.Obs ON Person.pID = ** ml. ** Obs.pId
oder
JOIN ml.Obs Obs ON Person.pID = Obs.pId
Es gibt andere Orte, an denen dies würde auch benötigt werden.
Wenn dies nicht der Fall ist, entfernen Sie sie aus der Abfrage, weil sie irrelevant und störend sind.