Как объяснил Фрэнк, PostgreSQL отклонит любой запрос, который не возвращает воспроизводимый набор строк.
Предположим, у вас есть запрос типа:
select a, b, agg(c)
from tbl
group by a
PostgreSQL отклонит егопотому что b
не указано в операторе group by
.Запустите это в MySQL, напротив, и оно будет принято.В последнем случае, однако, запускаются несколько вставок, обновлений и удалений, и порядок строк на страницах диска оказывается другим.
Если память служит, детали реализации таковы, что MySQL фактически будет сортировать поа, б и вернуть первый б в наборе.Но что касается стандарта SQL, его поведение не определено - и, несомненно, PostgreSQL не всегда сортирует перед запуском агрегатных функций.
Потенциально это может привести к различным значениямb
в наборе результатов в PostgreSQL.И, таким образом, PostgreSQL выдает ошибку, если вы не будете более конкретны:
select a, b, agg(c)
from tbl
group by a, b
Что выделил Фрэнк, так это то, что в PostgreSQL 9.1, если a
является первичным ключом, вы можете оставить b
неуказанным- планировщика научили игнорировать последующую группу по полям, когда применимые первичные ключи подразумевают уникальную строку.
В частности, для вашей проблемы вам нужно указать свою группу, как вы в настоящее время делаете, плюс каждое поле, на котором вы основываете агрегат, то есть "widgets"."id", "widgets"."user_id", [snip]
, но не такие вещи, как sum(amount)
, которые являются вызовами агрегатных функций.
Как примечание, не относящееся к теме, я неВы уверены, что ваша ORM / модель работает, но генерируемый SQL не оптимален.Многие из тех левых внешних объединений кажутся внутренними соединениями.Это позволит планировщику выбрать соответствующий порядок соединения, где это применимо.