L'errore di sintassi qui è che hai bisogno di un on
-clausola per il tuo left join
. Ma il problema concettuale di fondo è diverso:non puoi join
con una sottoquery dipendente .
Puoi correggere la tua domanda in questo modo:
select items.*
from items
LEFT OUTER JOIN (
select item_id, sum(purchase_details.quantity) as total
from purchase_details
GROUP BY purchase_details.item_id
) ABC on ABC.item_id = items.id;
Questo ha spostato il tuo where
interiore -condizione (che dipende da items.id
, che non è consentito, in quanto non rientra nell'ambito) al on
-clausola. Quindi item_id
viene aggiunto anche nel select
interno (poiché è necessario all'esterno).
Un modo diverso per scrivere questo sarebbe
select items.*,
(select sum(purchase_details.quantity)
from purchase_details
where purchase_details.item_id=items.id) as total
from items;
Qui hai una sottoquery dipendente :il where
interno -clause dipende dal items.id
esterno . Non hai bisogno di un group by
più, come where
-condizione usa già solo le righe per quell'elemento. (E comunque puoi anche restituire al massimo una riga in questo contesto.)
Entrambe le query sono equivalenti e possono (se l'ottimizzatore trova quel piano di esecuzione) internamente effettivamente essere eseguite esattamente allo stesso modo (che non è nulla di cui ti devi preoccupare molto, purché tu fornisca indici appropriati).
Quindi nel tuo caso puoi usare entrambi (e magari controllare quale è più veloce); se vuoi ottenere informazioni aggiuntive per quell'elemento, dovresti preferire il left join
-versione però, ad es. usa
...
LEFT OUTER JOIN (
select item_id,
sum(purchase_details.quantity) as total,
count(purchase_details.item_id) as cnt,
max(purchase_details.quantity) as max_quantity_per_order,
max(purchase_details.date) as latest_order,
...
from purchase_details
GROUP BY purchase_details.item_id
) ABC on ABC.item_id = items.id;