PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Rails expandindo campos com escopo, PG não gosta


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.