规范化数据库 - ONE到MANY - 搜索所有已连接的数据集

时间:2012-03-06 21:16:03

标签: mysql sql relational-database normalization

我正在尝试构建一个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不起作用,因为它显然永远不会返回1和2的genre_id,但这是我被卡住的地方。

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 个答案:

答案 0 :(得分:3)

这是一种方法:

    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

答案 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 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'

答案 2 :(得分:0)

                WHERE genre.genre_id ='1'
                AND genre.genre_id='2'

你的查询对吗?

if,那么这意味着它必须在两种情况下都是真的,但每行只有一个genre_id! 也许用'OR'或... genre.genre_id IN(1,2)

链接