Here's an example of the set up I'm using:
TITLES
id
name
DIRECTORS
id
name
ACTORS
id
name
MOVIES
id
movie_id
director_id
There can be several actors to a movie, so I use another join table:
MOVIES_ACTORS
id
movie_id
actor_id
This all works fine, except for one problem... i get several rows for one movie. So it comes out like this:
Star Wars - George Lucas - Harrison Ford
Star Wars - George Lucas - James Earl Jones
Star Wars - George Lucas - Yoda
King Kong - Peter Jackson - Jack Black
School of Rock - NULL - Jack Black
This is a problem because I don't want 3 results for Star Wars, I want one result row with 3 columns for the actors. Have three separate rows causes problems because:
1. If I were to limit the results to say, 3 I would only get Star Wars as a result.
2. When I display the results with PHP I have to build an elaborate array and loop through the result set 3 times just to avoid showing more than one result for the same movie in the list.
Here's my query:
SELECT
m.id, t.name, dir.name, act.name
FROM movies m
JOIN titles t ON t.id = m.title_id
LEFT OUTER JOIN directors dir ON dir.id = m.director_id
LEFT OUTER JOIN movies_actors ma ON ma.movie_id = m.id
LEFT OUTER JOIN actors a ON ma.actor_id = a.id
---------------------------------------------------------------
The solution is a GROUP_CONCAT on the terms you want to combine
SELECT m.id, t.name,
group_concat(dir.name) AS directors, group_concat(act.name) AS actors
FROM movies             AS m 
JOIN titles             AS t   ON t.id = m.title_id 
LEFT JOIN directors     AS dir ON dir.id = m.director_id 
LEFT JOIN movies_actors AS ma  ON ma.movie_id = m.id 
LEFT JOIN actors        AS a   ON ma.actor_id = a.id
GROUP BY t.name
It combines those columns as a comma-separated list.  You can also define a
separator...
GROUP_CONCAT(dir.name SEPARATOR '; ') 
 
 
No comments:
Post a Comment