【问题标题】:Normalizing table LIMIT issue规范化表 LIMIT 问题
【发布时间】:2014-02-03 14:10:09
【问题描述】:

我有 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 |
+-----------+---------+

【问题讨论】:

  • 我认为你的联想是错误的。而不是song *--1 song_author *--1 author,你真的有song 1--* song_author *--1 author,对吧?一首歌可以有很多作者(通过 song_author),一个作者可以有很多歌曲(通过 song_author)。
  • @omgitsfletch 是的,我会解决的,你

标签: mysql sql normalization database-normalization


【解决方案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

【讨论】:

    【解决方案2】:

    明确地说,您的目标到底是什么?似乎您想一次获取一定数量的歌曲(示例中为 10 首),以及所述歌曲的所有相关作者。但是,如果这些 [song, author] 记录元组中的多个表示同一首歌曲,那么您最终会得到 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
    

    【讨论】:

    • 然而,这并不是世界上最有效的方法。您为了数据呈现而牺牲了一些速度,这可能是不可接受的,具体取决于系统中的数据规模。如果你需要更高效的东西,我会避免这种方法,做一个依赖子查询,比如 Marcin 建议的那种,并在查询后用实际的编程语言组合你的艺术家。
    猜你喜欢
    • 2020-03-06
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多