views:

374

answers:

2

The question is to get table column data and use it as a value list for IN function;

For this example I created 2 tables: movies and genres

Table "movies" contains 3 columns: id, name and genre. Table "genres" contains 2 columns: id and name.

+- movies-+
|         |- movie_id - int(11) - AUTO_INCREMENT - PRIMARY
|         |- movie_name - varchar(255)
|         |- movie_genres - varchar(255)
|
|         
+- genres-+
          |- genre_id - int(11) - AUTO_INCREMENT - PRIMARY
          |- genre_name - varchar(255)

Both tables contain some dummy data:

+----------+------------+--------------+
| movie_id | movie_name | movie_genres |
+----------+------------+--------------+
|        1 | MOVIE 1    | 2,3,1        |
|        2 | MOVIE 2    | 2,4          |
|        3 | MOVIE 3    | 1,3          |
|        4 | MOVIE 4    | 3,4          |
+----------+------------+--------------+

+----------+------------+
| genre_id | genre_name |
+----------+------------+
|        1 | Comedy     |
|        2 | Fantasy    |
|        3 | Action     |
|        4 | Mystery    |
+----------+------------+

My goal is to get result like this:

+----------+------------+--------------+-----------------------+
| movie_id | movie_name | movie_genres |   movie_genre_names   |
+----------+------------+--------------+-----------------------+
|        1 | MOVIE 1    | 2,3,1        | Fantasy,Action,Comedy |
|        2 | MOVIE 2    | 2,4          | Fantasy,Mystery       |
|        3 | MOVIE 3    | 1,3          | Comedy,Action         |
|        4 | MOVIE 4    | 3,4          | Action,Mystery        |
+----------+------------+--------------+-----------------------+

I'm using this query and it's partly working only problem is that it uses the first value of the movie_genres field in the IN value list.

SELECT `m` . * , GROUP_CONCAT( `g`.`genre_name` ) AS `movie_genre_names`
FROM `genres` AS `g`
LEFT JOIN `movies` AS `m` ON ( `g`.`genre_id`
IN (
`m`.`movie_genres`
) )
WHERE `g`.`genre_id`
IN (
(
SELECT `movie_genres`
FROM `movies`
WHERE `movie_id` =1
)
)
GROUP BY 1 =1

The results greatly differ from the one I want:

+----------+------------+--------------+-------------------+
| movie_id | movie_name | movie_genres | movie_genre_names |
+----------+------------+--------------+-------------------+
|        1 | MOVIE 1    | 2,3,1        | Fantasy,Fantasy   |
+----------+------------+--------------+-------------------+

Sorry if I missed some data I'm new to mysql.

What query should I use to get the wanted results?

+1  A: 

This is a bad design. You should create a many-to-many link table (movie_id, genre_id)

If you cannot change this design, however, use this query:

SELECT  movie.*
        (
        SELECT  GROUP_CONCAT(genre_name)
        FROM    genres
        WHERE   find_in_set(genre_id, movie_genres)
        ) as movie_genre_names
FROM    movies
Quassnoi
Thanks. Final query looks like this.SELECT *, (SELECT GROUP_CONCAT(genre_name) FROM `genres` WHERE FIND_IN_SET(genre_id, movie_genres)) AS `movie_genre_names` FROM `movies`;
George
A: 

Your best solution will be to add a third table called movie_genres. This will make your life easier.

Justin Giboney
Quassnoi beat me to it =(
Justin Giboney