views:

129

answers:

4

I have a list of TV shows stored in 1 table. Another table stores show genres (action, romance, comedy).

Most shows usually have more than 1 genre, so having a single tv_genre column and putting the genre ID in there isn't an option.

I could create a look up table which would store tv show id + genre id, and I could insert 1 row for every genre associated with the show.

Where things get fuzzy for me is when I want to output a list of shows on the index, and genre names associated with the tv show. How would I tie the 3 tables together into 1 efficient query (instead of running a separate query for each item on index, getting its genres).

For the purposes of this post, the tables are as follows

TV Show Table
- tv_id
- tv_name

Genre Table
- genre_id
- genre_name

Thanks!

+5  A: 

http://dev.mysql.com/doc/refman/5.0/en/join.html

JOIN is the heart of SQL. you'll wind up with something like

select tv_name, genre_name
from tvshows
   left join shows_genres on tvshows.tv_id = shows_genres.tv_id
   left join genres on genres.genre_id = shows_genres.genre_id
Jimmy
Beat me to it. :) +1
MitMaro
You'll wind up with a show vanishing if it doesn't have any genres; you probably want left join.
derobert
@derobert: good point. What is proper SO-etiquette here, editing my answer or voting up yours?
Jimmy
actually, i guess the group_concat is worth the vote regardless :)
Jimmy
This will only work if there is one genre per show.... how do you get it to show multiple genres?
+3  A: 

You can use MySQL's GROUP_CONCAT function:

SELECT
    t.tv_name, GROUP_CONCAT(g.genre_name)
  FROM
    tv_shows t
    LEFT JOIN show_genres sg ON (t.tv_id = sg.tv_id)
    LEFT JOIN genres g ON (sg.genre_id = g.genre_id)
  WHERE
    /* whatever */
  GROUP BY t.tv_name

Your index page won't be particularly efficient; it can't be: you're pulling the entire table (well, all three tables). If it ever becomes a problem, look into caching.

derobert
Thats exactly how I do it... and its causing load problems for me. Remvoing group_concat statement cuts execution time from 1 second, to 0.1
The alternative is not to do the group_concat, and do it in your application (you'll get back one row per show/genre pair). Or, just cache it. How important is it that an index be completely current, is 1 hour old OK?
derobert
Caching would be very difficult to implement, since there are about 7 sorting methods, and about 1200 pages worth of content.
A: 

Show-Genre Table - rv_id int - genre_id int

 select tv_show.name, genre.genre_name from tv_show,genre, show_genre where 
show_genre.tv_id = tv_show.tv_id and genre.genre_id=show_genre.genre_id

Something like this

Ilya Biryukov
A: 

May not be the best sql but my idea was

select tv_name, genre_name
from tv_table, genre_table, lookup_table
where
    tv_table.tv_name = "superman"
    and
    tv_table.tv_id = lookup_table.tv_id
    and
    lookup_table.genre_id = genre_table.genre_id
lumpynose