#mysql #sql
#mysql #sql
Вопрос:
У меня есть база данных со следующими таблицами:
- фильмы: (идентификатор, название)
- субъект: (идентификатор, имя)
- директор: (удостоверение личности, имя)
- movies_actors: (movie_id, actor_id)
- movies_directors: (movie_id, director_id)
Последние две таблицы представляют отношения между фильмами и актерами и режиссерами. Я хочу получить список фильмов, включая их актеров и режиссеров, разделенных запятыми.
Я попробовал следующее, чтобы получить эту информацию, например:
SELECT movie.title,
GROUP_CONCAT((SELECT name FROM actors WHERE id=movies_actors.actor) SEPARATOR ', ') AS 'actors',
GROUP_CONCAT((SELECT name FROM directors WHERE id=movies_directors.director) SEPARATOR ', ') AS 'directors'
FROM movies
LEFT JOIN movies_actors ON movies_actors.movie = movies.id
LEFT JOIN movies_directors ON movies_directors.movie = movies.id
Однако это возвращает результат следующим образом:
Название | действующие лица | директора |
---|---|---|
Название фильма | ActorA, ActorB, ActorC | directorA, directorA, directorA |
Несмотря на то, что в фильме только один режиссер, он отображается 3 раза. Я хотел бы получить следующий результат:
Название | действующие лица | директора |
---|---|---|
Название фильма | ActorA, ActorB, ActorC | directorA |
Как мне это сделать?
Ответ №1:
Лучшее решение — это подзапросы. Для этой цели вы можете использовать коррелированные подзапросы:
SELECT m.title,
(SELECT GROUP_CONCAT(a.name, SEPARATOR ', ')
FROM movies_actors ma JOIN
actors a
ON a.id = ma.actor
WHERE ma.movie = m.id
) AS actors,
(SELECT GROUP_CONCAT(d.name, SEPARATOR ', ')
FROM movies_directors md JOIN
directors d
ON d.id = md.director
WHERE md.movie = m.id
) AS directors
FROM movies m;
Обратите внимание, что здесь происходит. Для каждого фильма каждый подзапрос собирает все интересующие строки и объединяет имена в один столбец. Во внешнем запросе агрегирование не требуется, поскольку каждый подзапрос возвращает ровно одну строку.
Когда вы объединяетесь в таблицах соединений во внешнем запросе, вы получаете декартово произведение актеров и режиссеров для каждого фильма — и это отбрасывает результаты.