Группа по указанному столбцу в PostgreSQL

Возможно, этот вопрос немного глуп, но я в замешательстве.

Как группировать записи по указанному столбцу?:)

Item.group(:category_id)

не работает...

В нем говорится:

ActiveRecord:: StatementInvalid: PGError: ERROR: столбец "items.id" должен появиться в предложении GROUP BY или использоваться в агрегатной функции LINE 1: SELECT "items". * FROM "items" GROUP BY category_id

Какую функцию агрегата я должен использовать?

Пожалуйста, не могли бы вы привести простой пример.

Ответ 1

Вам нужно будет определить, как группировать значения, которые имеют один и тот же category_id. Объединить их? Вычислить сумму?

Чтобы создать список значений, разделенных запятыми, ваш оператор может выглядеть так:

SELECT category_id
      ,string_agg(col1, ', ') AS col1_list
      ,string_agg(col2, ', ') AS col2_list
FROM   items
GROUP  BY category_id

Вам нужен Postgres 9.0 или новее для string_agg(col1, ', '). В более старых версиях вы можете заменить array_to_string(array_agg(col1), ', '). Более общие функции здесь.

Чтобы агрегировать значения в PostgreSQL, это явно отличный подход, а не агрегирование значений в клиенте. Postgres работает очень быстро и сокращает (сетевой) трафик.

Ответ 2

Вы можете использовать sum, avg, count или любую другую функцию агрегации. Подробнее об этой теме вы можете найти здесь.

Но, похоже, вам не нужно использовать SQL-группировку.

Попробуйте взять все записи, а затем используйте Array#collect для группировки Item на category_id

Ответ 3

Группирование в SQL означает, что сервер группирует одну или несколько записей из таблицы базы данных в одну результирующую строку. Итак, если вы, например, group by category_id, у вас может быть несколько записей, соответствующих данной категории, поэтому вы не можете ожидать, что база данных вернет столбцы all из таблицы (что означает SELECT * фактически делает).

Вместо этого, когда вы используете GROUP BY, вы можете SELECT:

  • столбцы, которые вы сгруппировали, и/или
  • совокупные функции, выполняемые во всех записях, относящихся к результирующей группе

В зависимости от того, что вам нужно, измените свой .select соответственно.