2015-09-21 2 views
1

Следующий код получает все residences, у которых есть все amenities, которые перечислены в id_list. Он работает с вне проблемы с SQLite, но возникает ошибка с PostgreSQL:Решение PG :: GroupingError: ERROR

id_list = [48, 49] 
Residence.joins(:listed_amenities). 
      where(listed_amenities: {amenity_id: id_list}). 
      references(:listed_amenities). 
      group(:residence_id). 
      having("count(*) = ?", id_list.size) 

Ошибка в версии PostgreSQL:

Rails error message

Что я должен изменить, чтобы заставить его работать с PostgreSQL ?

+0

Отсутствие ноу-хау Markdown не позволило мне включить код ошибки в «правильный» способ. Я думал, что образ был наименее злым. Я посмотрел на другие вопросы, но не смог найти ответ на вопрос. – wintermeyer

+0

Чтобы вставить ваши журналы в виде текста, просто отложите каждую строку на четыре пробела, как и код. – ahmacleod

ответ

1

Несколько вещей:

  1. references следует использовать только с includes; он сообщает ActiveRecord выполнить соединение, поэтому он избыточен при использовании явного joins.

  2. Вам необходимо полностью квалифицировать аргумент group, то есть group('residences.id').

Например,

id_list = [48, 49] 
Residence.joins(:listed_amenities). 
      where(listed_amenities: { amenity_id: id_list }). 
      group('residences.id'). 
      having('COUNT(*) = ?", id_list.size) 
1

Запрос Рубин код расширяется до выбирает все поля из резиденций таблицы (?):

SELECT "residences".* 
    FROM "residences" 
INNER JOIN "listed_amenities" 
    ON "listed_amentities"."residence_id" = "residences"."id" 
WHERE "listed_amenities"."amenity_id" IN (48,49) 
GROUP BY "residence_id" 
HAVING count(*) = 2 
ORDER BY "residences"."id" ASC 
LIMIT 1; 

С Postgres manual, когда ГРУППА BY присутствует, для выражений списка SELECT недопустимо ссылаться на негрупповые столбцы, кроме как внутри агрегатных функций, или если негруппированный столбец функционально зависит от сгруппированных столбцов, поскольку в противном случае было бы больше, чем одно возможное значение для возврата негруппированного столбца.

Вам нужно либо сгруппировать по всем полям, к которым не применяются агрегированные функции, или делать это по-другому. Из запроса, похоже, вам нужно только сканировать таблицу amentities получить жительство ID, который вы ищете:

SELECT "residence_id" 
    FROM "listed_amenities" 
WHERE "listed_amenities"."amenity_id" IN (48,49) 
GROUP BY "residence_id" 
HAVING count(*) = 2 
ORDER BY "residences"."id" ASC 
LIMIT 1 

А потом получать данные на жительство с этим идентификатором. Или в одном запросе:

SELECT "residences".* 
    FROM "residences" 
WHERE "id" IN (SELECT "residence_id" 
        FROM "listed_amenities" 
       WHERE "listed_amenities"."amenity_id" IN (48,49) 
       GROUP BY "residence_id" 
       HAVING count(*) = 2 
       ORDER BY "residences"."id" ASC 
       LIMIT 1 
       ); 
Смежные вопросы