Оптимизация SQL-запроса на основе атрибута (не имеющего определенного значения) в объединенной таблице - PullRequest
1 голос
/ 10 марта 2019

Структура моей модели: Фильм has_many :captions.Язык надписи может быть «en», «de», «fr» ...

Проблема: эффективный запрос для выбора фильмов, в которых нет надписей с языком «en».

Приложение, которое требуется выше, работает на Rails, и для этого я сейчас использую что-то подобное в модели Caption:

def self.ids_of_movies_without_caption_in_en
  a = (1..(Movie.last.lp.to_i)).to_a
  b = Caption.in_lang("en").collect {|h| h.movie_id }
  (a - b)
end

Как видите, я собираю идентификаторы (lp) извсе фильмы, а затем я удаляю из этого массива идентификаторы тех фильмов, где в заголовках есть «en» в качестве языка.Результатом является массив идентификаторов фильмов, которые мне нужны.

Выше работает, но, как вы можете себе представить, он довольно «тяжелый».Я считаю, что есть лучший (и, возможно, тривиальный) подход к этому.Однако, будучи «свежим» с SQL, я прошу дать некоторые рекомендации по написанию эффективного запроса.Это работает на PostgreSQL
Реализация в Rails (5.2) будет дополнительным бонусом!

Это ситуация: Допустим, в базе данных есть 1000 фильмов и 4000 подписей к этим фильмам.Конечно, есть фильмы, в которых нет подписи.Из этих 4000 подписей 400 написаны на языке en.Запрос, который я ищу, вернул бы 600 фильмов, где заголовок в "en" не существует (включая фильмы с 0 заголовками).

1 Ответ

0 голосов
/ 10 марта 2019

Это довольно просто в SQL. Я не совсем уверен, как выглядят таблицы, но что-то вроде этого:

select movie_id
from captions
group by movie_id
having not bool_or(language = 'en');

Если вы хотите фильмы без заголовков, используйте not exists:

select m.movie_id
from movies m
where not exists (select 1
                  from captions c
                  where c.movie_id = m.movie_id and
                        m.language = 'en'
                 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...