Jak wyjaśnił Frank, PostgreSQL odrzuci każde zapytanie, które nie zwróci powtarzalnego zestawu wierszy.
Załóżmy, że masz zapytanie takie jak:
select a, b, agg(c)
from tbl
group by a
PostgreSQL odrzuci go, ponieważ b
pozostaje nieokreślony w grupie group by
oświadczenie. Uruchom to w MySQL, a zostanie zaakceptowane. Jednak w tym drugim przypadku odpal kilka wstawek, aktualizacji i usunięć, a kolejność wierszy na stronach dysku będzie inna.
Jeśli pamięć obsługuje, szczegóły implementacji są takie, że MySQL będzie faktycznie sortował według a, b i zwracał pierwszy b w zestawie. Ale jeśli chodzi o standard SQL, zachowanie jest nieokreślone — i oczywiście PostgreSQL nie zawsze sortuj przed uruchomieniem funkcji agregujących.
Potencjalnie może to spowodować różne wartości b
w wyniku ustawionym w PostgreSQL. W ten sposób PostgreSQL wyświetla błąd, chyba że jesteś bardziej precyzyjny:
select a, b, agg(c)
from tbl
group by a, b
Frank podkreślił, że w PostgreSQL 9.1, jeśli a
jest kluczem podstawowym, wtedy możesz zostawić b
nieokreślone — planista został nauczony ignorowania kolejnych grup według pól, gdy odpowiednie klucze podstawowe oznaczają unikalny wiersz.
Zwłaszcza w przypadku swojego problemu musisz określić swoją grupę, tak jak obecnie, plus każde pole, na którym opierasz swoją agregację, np. "widgets"."id", "widgets"."user_id", [snip]
ale nie takie rzeczy jak sum(amount)
, które są wywołaniami funkcji agregujących.
Na marginesie, nie jestem pewien, jak działa twój ORM/model, ale generowany przez niego kod SQL nie jest optymalny. Wiele z tych lewych sprzężeń zewnętrznych wydaje się, że powinny być sprzężeniami wewnętrznymi. Spowoduje to, że planista będzie mógł wybrać odpowiednią kolejność łączenia, jeśli ma to zastosowanie.