#sql #arrays #select
#sql #массивы #выберите
Вопрос:
Работая в приложении Rails, у меня есть следующая структура таблицы (только соответствующие столбцы)
Фотографии (идентификатор: целое число) Теги (photo_id: целое число, tag_id: целое число) Теги (идентификатор: целое число, имя: строка)
У меня есть следующий SQL-запрос:
SELECT distinct photos.*
FROM "photos" INNER JOIN "taggings" ON "photos"."id" = "taggings"."photo_id"
INNER JOIN "tags" ON "tags"."id" = "taggings"."tag_id"
WHERE "tags"."name" IN ('foo', 'bar')
Когда я генерирую этот запрос, я передаю массив тегов (в данном случае ["foo","bar"]
). Запрос правильно выполняет поиск фотографий, которые соответствуют ЛЮБОМУ из тегов, переданных в массиве.
Как я могу изменить этот запрос, чтобы выбирать записи со ВСЕМИ заданными тегами (т. Е. Фотография соответствует, только если помечена «foo» И «bar», вместо выбора записей с ЛЮБЫМ из заданных тегов?
Ответ №1:
Может быть лучший способ, но это должно сработать
SELECT photos.id,max(otherColumn)
FROM "photos"
INNER JOIN "taggings"
ON "photos"."id" = "taggings"."photo_id"
INNER JOIN "tags"
ON "tags"."id" = "taggings"."tag_id"
WHERE "tags"."name" IN ('foo', 'bar')
group by photos.id
having count(*) = 2 --2 is the number of items in your array of tags.
Комментарии:
1. Это работает, но в PostgreSQL я постоянно сталкиваюсь с классической «Ошибкой PG: столбец ______ должен быть включен в предложение Group By или использоваться в агрегатной функции». Я могу избежать этого, сгруппировав по всем столбцам, но знаете ли вы лучшее решение?
Ответ №2:
Если вы используете rails, вам не нужен запрос для этого.
Tags.find(1).taggings
должен предоставить вам массив всех фотографий с этим тегом
you can also use Tags.find_by_name("foo").taggings
вы можете аналогичным образом выполнить итерацию по всем тегам и собрать массивы, а затем просто сделать что-то подобное с имеющимися у вас массивами.
[ 1, 1, 3, 5 ] amp; [ 1, 2, 3 ] #=> [ 1, 3 ]
В основном ‘и’ массивы и получите уникальные фотографии.Таким образом, вы можете получить фотографии, соответствующие всем тегам.
Комментарии:
1. Не очень хорошая идея, поскольку для этого требуется несколько вызовов базы данных и потенциально возврат большого количества данных в память. Конечно, это может быть хорошо для небольшого набора данных и небольшого числа пользователей.
2. Нет, это не сработает. Я использую это для создания метода поиска по фотографиям, который я могу связать с другими методами. Он должен исходить из фотографий, чтобы его можно было ограничить и т.д.