PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Binari che espandono i campi con l'ambito, a PG non piace

Come ha spiegato Frank, PostgreSQL rifiuterà qualsiasi query che non restituisca un insieme riproducibile di righe.

Supponiamo che tu abbia una query del tipo:

select a, b, agg(c)
from tbl
group by a

PostgreSQL lo rifiuterà perché b non è specificato nel group by dichiarazione. Eseguilo in MySQL, al contrario, e sarà accettato. In quest'ultimo caso, tuttavia, vengono eseguiti alcuni inserimenti, aggiornamenti ed eliminazioni e l'ordine delle righe sulle pagine del disco risulta diverso.

Se la memoria serve, i dettagli di implementazione sono tali che MySQL ordinerà effettivamente per a, b e restituirà il primo b nell'insieme. Ma per quanto riguarda lo standard SQL, il comportamento non è specificato e, in effetti, PostgreSQL non ordina sempre prima di eseguire le funzioni aggregate.

Potenzialmente, ciò potrebbe comportare valori diversi di b nel set di risultati in PostgreSQL. E quindi, PostgreSQL restituisce un errore a meno che tu non sia più specifico:

select a, b, agg(c)
from tbl
group by a, b

Ciò che Frank ha evidenziato è che, in PostgreSQL 9.1, se a è la chiave primaria, che puoi lasciare b non specificato:al pianificatore è stato insegnato a ignorare il raggruppamento successivo per i campi quando le chiavi primarie applicabili implicano una riga univoca.

Per il tuo problema in particolare, devi specificare il tuo gruppo come fai attualmente, più ogni campo su cui stai basando il tuo aggregato, ad esempio "widgets"."id", "widgets"."user_id", [snip] ma non cose come sum(amount) , che sono le chiamate di funzione aggregate.

Come nota a margine fuori tema, non sono sicuro di come funzioni il tuo ORM/modello, ma l'SQL che sta generando non è ottimale. Molte di queste giunzioni esterne sinistre sembrano come dovrebbero essere giunzioni interne. Ciò consentirà al pianificatore di scegliere un ordine di unione appropriato, ove applicabile.