Вложенный запрос в squeel
Краткая версия: Как мне написать этот запрос в squeel?
SELECT OneTable.*, my_count
FROM OneTable JOIN (
SELECT DISTINCT one_id, count(*) AS my_count
FROM AnotherTable
GROUP BY one_id
) counts
ON OneTable.id=counts.one_id
Длинная версия: rocket_tag - это драгоценный камень, который добавляет простые теги к моделям. Добавляет метод tagged_with
, Предположим, что моя модель User
, с идентификатором и именем, я мог бы призвать User.tagged_with ['admin','sales']
, Внутренне он использует этот код squeel:
select{count(~id).as(tags_count)}
.select("#{self.table_name}.*").
joins{tags}.
where{tags.name.in(my{tags_list})}.
group{~id}
Который генерирует этот запрос:
SELECT count(users.id) AS tags_count, users.*
FROM users INNER JOIN taggings
ON taggings.taggable_id = users.id
AND taggings.taggable_type = 'User'
INNER JOIN tags
ON tags.id = taggings.tag_id
WHERE tags.name IN ('admin','sales')
GROUP BY users.id
Некоторые РСУБД довольны этим, но postgres жалуется:
ERROR: column "users.name" must appear in the GROUP BY
clause or be used in an aggregate function
Я полагаю, что более приятный способ написать запрос:
SELECT users.*, tags_count FROM users INNER JOIN (
SELECT DISTINCT taggable_id, count(*) AS tags_count
FROM taggings INNER JOIN tags
ON tags.id = taggings.tag_id
WHERE tags.name IN ('admin','sales')
GROUP BY taggable_id
) tag_counts
ON users.id = tag_counts.taggable_id
Есть ли способ выразить это с помощью Squeel?
1 ответ
Я не знаю о Squeel, но ошибка, которую вы видите, может быть исправлена путем обновления PostgreSQL.
Некоторые РСУБД довольны этим, но postgres жалуется:
ОШИБКА: столбец "users.name" должен появляться в предложении GROUP BY или использоваться в статистической функции
Начиная с PostgreSQL 9.1, после того, как вы перечислите первичный ключ в GROUP BY, вы можете пропустить дополнительные столбцы для этой таблицы и по-прежнему использовать их в списке SELECT. Примечания к выпуску для версии 9.1 говорят нам:
Разрешить не-GROUP BY столбцы в списке целей запроса, если в предложении GROUP BY указан первичный ключ
Кстати, ваш альтернативный запрос может быть упрощен, дополнительный DISTINCT
будет излишним.
SELECT o.*, c.my_count
FROM onetable o
JOIN (
SELECT one_id, count(*) AS my_count
FROM anothertable
GROUP BY one_id
) c ON o.id = counts.one_id