规范化表LIMIT问题

时间:2014-02-03 05:24:38

标签: mysql sql normalization database-normalization

我有3个表songauthorsong_author

连接是song 1--* song_author 1--* author

我使用像

这样的查询
SELECT *
FROM song
LEFT JOIN song_author ON s_id = sa_song
LEFT JOIN author ON sa_author = a_id

对于将导致3行的给定示例:

John - How beautiful it is
John - Awesome
George - Awesome

我正在填充我的对象,所以没关系。

但是,我想添加一个LIMIT子句,但因为它只为一首歌曲返回几行,LIMIT 10并不总是显示10首歌曲。

我知道的另一种可能性是打印所有歌曲,然后在里面进行第二次查询,但这会产生O(n),我想避免。

author:
+------+--------+
| a_id | a_name |
+------+--------+
|    1 | John   |
|    2 | George |
+------+--------+

song:
+------+---------------------+
| s_id |       s_name        |
+------+---------------------+
|    1 | How beautiful it is |
|    2 | Awesome             |
+------+---------------------+

song_author:
+-----------+---------+
| sa_author | sa_song |
+-----------+---------+
|         1 |       1 |
|         1 |       2 |
|         2 |       2 |
+-----------+---------+

2 个答案:

答案 0 :(得分:1)

你可以尝试这样的事情:

SELECT *
FROM
    (SELECT *
    FROM song
    LIMIT 10) r
LEFT JOIN song_author ON r.s_id = sa_song
LEFT JOIN author ON sa_author = a_id

答案 1 :(得分:0)

要说清楚,你的目标究竟是什么?您似乎想要一次获取一定数量的歌曲(示例中为10个),以及所有相关作者的歌曲。但是,如果这些[歌曲,作者]的多个记录元组代表同一首歌曲,那么你最终会有10首唱片,但不到10首实际歌曲。

我喜欢Marcin的方法,但如果你想避免使用子查询和临时表,你可以使用MySQL内置的功能:GROUP_CONCAT()

SELECT
    s_name,
    GROUP_CONCAT(DISTINCT a_name SEPARATOR '|')
FROM
    song
LEFT JOIN
    song_author ON sa_song = s_id
LEFT JOIN
    author ON a_id = sa_author
GROUP BY
    s_name
LIMIT 10