Нормализованная база данных - от ОДНОГО до МНОГО - Поиск по всем объединенным наборам данных - PullRequest
3 голосов
/ 07 марта 2012

Я пытаюсь создать запрос MySQL, который позволит мне извлечь название песни из трека в базе данных, имеющей жанр Pop и Electronic.

+----------------------------------------------------+
TABLE: SONG
+----------------------------------------------------+
song_id  | title       |  
1        | song name   | 


+----------------------------------------------------+
TABLE: GENRE
+----------------------------------------------------+
genre_id   | name       | 
1          | Pop        |    
2          | Electronic |   


+----------------------------------------------------+
TABLE: SONG_GENRE
+----------------------------------------------------+
genre_id  | song_id | 
1         | 1       | 
2         | 1       | 

Этот SQL не работает, так как он, очевидно, никогда не будет возвращать genre_id, равный 1 и 2, но я застрял здесь.

SELECT DISTINCT song.song_id, song.title
                    FROM song
                    LEFT JOIN song_genre ON song_genre.song_id = song.song_id
                    LEFT JOIN genre ON genre.genre_id = song_genre.genre_id
                    WHERE genre.genre_id ='1'
                    AND genre.genre_id='2'

Если бы кто-то мог указать мне правильное направление, я был бы очень благодарен!

Ответы [ 3 ]

3 голосов
/ 07 марта 2012

Вот один из способов сделать это:

    SELECT DISTINCT song.song_id, song.title
    FROM song
    INNER JOIN (SELECT songid FROM song_genre WHERE song_genre.genre_id ='1') genre1 
         ON genre1.song_id = song.song_id
    INNER JOIN (SELECT songid FROM song_genre WHERE song_genre.genre_id ='2') genre2 
         ON genre2.song_id = song.song_id

Еще один способ, который может быть более эффективным. Это предполагает, что в song_genre нет дуплей. COUNT (*) = X, где X равно количеству перечисленных жанров.

SELECT DISTINCT song.song_id, song.title
FROM song
INNER JOIN (SELECT songid, COUNT(*) FROM song_genre 
WHERE genre_id IN ('1','2') 
GROUP BY songid HAVING COUNT(*) = 2) genre1 ON genre1.song_id = song.song_id
2 голосов
/ 07 марта 2012

Предполагая, что данные нормализованы и символ, как в вашем примере:

SELECT
   song.song_id, 
   song.title
FROM 
   song
      INNER JOIN song_genre ON song_genre.song_id = song.song_id
      INNER JOIN genre ON genre.genre_id= song_genre.genre_id
WHERE 
   genre.genre_id in ('1', '2')

Изменено в соответствии с вашим комментарием:

SELECT
   song.song_id, 
   song.title
FROM 
   song
      INNER JOIN song_genre ON song_genre.song_id = song.song_id
      INNER JOIN genre g1 ON g1.genre_id = song_genre.genre_id
      INNER JOIN genre g2 ON g2.genre_id = song_genre.genre_id
WHERE 
   g1.genre_id = '1' and
   g2.genre_id = '2'
0 голосов
/ 07 марта 2012
                WHERE genre.genre_id ='1'
                AND genre.genre_id='2'

Ваш запрос правильный?

если, то это означает, что это должно быть верно в обоих случаях, но у вас есть в строке только один genre_id! возможно, связать это с 'ИЛИ' или ... genre.genre_id IN (1,2)

...