Como Frank explicou, o PostgreSQL rejeitará qualquer consulta que não retorne um conjunto reproduzível de linhas.
Suponha que você tenha uma consulta como:
select a, b, agg(c)
from tbl
group by a
O PostgreSQL irá rejeitá-lo porque
b
é deixado não especificado no group by
declaração. Execute isso no MySQL, por outro lado, e ele será aceito. No último caso, no entanto, acione algumas inserções, atualizações e exclusões, e a ordem das linhas nas páginas do disco acaba sendo diferente. Se a memória servir, os detalhes da implementação são para que o MySQL realmente classifique por a, b e retorne o primeiro b no conjunto. Mas no que diz respeito ao padrão SQL, o comportamento não é especificado -- e com certeza, o PostgreSQL não sempre classifique antes de executar funções agregadas.
Potencialmente, isso pode resultar em valores diferentes de
b
no conjunto de resultados no PostgreSQL. E assim, o PostgreSQL gera um erro, a menos que você seja mais específico:select a, b, agg(c)
from tbl
group by a, b
O que Frank destacou é que, no PostgreSQL 9.1, se
a
é a chave primária, então você pode deixar b
unspecified -- o planejador foi ensinado a ignorar o agrupamento por campos subsequentes quando as chaves primárias aplicáveis implicarem uma linha exclusiva. Para o seu problema em particular, você precisa especificar seu grupo por como você faz atualmente, mais todos os campos nos quais você está baseando sua agregação, ou seja,
"widgets"."id", "widgets"."user_id", [snip]
mas não coisas como sum(amount)
, que são as chamadas de função agregadas. Como uma nota lateral fora do tópico, não tenho certeza de como seu ORM/modelo funciona, mas o SQL que está gerando não é o ideal. Muitas dessas junções externas esquerdas parecem ser junções internas. Isso resultará em permitir que o planejador escolha uma ordem de associação apropriada, quando aplicável.