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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top