Как сопоставить несколько строк, используя INNER JOIN с MySQL? - PullRequest
0 голосов
/ 03 апреля 2020

Как правильно выбрать фильмы с надписями «Действие» и «Драма» с помощью INNER JOIN?

Я пробовал этот запрос, результатом должен быть «Снят, Крестный отец», но, результат не возвращается.

SELECT 
    f.film_guid,
    f.film_name
FROM
    films as f
INNER JOIN
    film_labels as l ON l.film_guid = f.film_guid
WHERE
    l.label = 'Action' AND l.label = 'Drama'

Таблица: фильмы

+------------+----------------+
| film_guid  | film_name      |
+------------+----------------+
| filmguid_1 | Taken          |
| filmguid_2 | Matrix         |
| filmguid_3 | The Godfather  |
+------------+----------------+

Таблица: film_labels

+------------+----------------+
| film_guid  | label          |
+------------+----------------+
| filmguid_1 | Action         |
| filmguid_1 | Drama          |
| filmguid_1 | Family         |
| filmguid_2 | Action         |
| filmguid_3 | Action         |
| filmguid_3 | Drama          |
+------------+----------------+

1 Ответ

2 голосов
/ 03 апреля 2020

Вы ищете строки в film_labels, которые содержат как действие, так и драму, чего не может быть. Вам необходимо выполнить поиск по меткам, которые соответствуют данному фильму, которые предлагают агрегирование:

SELECT f.film_guid, f.film_name
FROM films as f
INNER JOIN film_labels as l ON l.film_guid = f.film_guid
WHERE l.label IN ('Action', 'Drama')  -- either one, or the other
GROUP BY f.film_guid, f.film_name
HAVING COUNT(*) = 2                   -- both match

Обратите внимание, что вы также можете использовать exists с коррелированным подзапросом. Это немного длиннее для ввода, но может быть более эффективным (с правильными индексами на месте), так как это устраняет необходимость в агрегировании:

SELECT f.*
FROM films as f
WHERE
    EXISTS (SELECT 1 FROM film_labels l WHERE l.film_guid = f.film_guid AND l.label = 'Action')
    AND EXISTS (SELECT 1 FROM film_labels l WHERE l.film_guid = f.film_guid AND l.label = 'Drama')

Для производительности со вторым запросом , вы хотите индекс на film_labels(film_guid , label).

...