【问题标题】:Select N rows from a table with a non-unique foreign key从具有非唯一外键的表中选择 N 行
【发布时间】:2009-04-24 14:18:39
【问题描述】:

我之前问过similar question,虽然我得到的答案很精彩,但我可能需要澄清一下。

就像This question 一样,我想根据列中的值返回 N 行。

我的例子是我有一个博客,我想在其中展示我的帖子以及 cmets 的预览。准确地说是最后三个 cmets。

我有我需要的帖子,但我正在绞尽脑汁让 cmets 正确。 cmets 表有一个 post_id 的外键,显然多个 cmets 可以附加到一个帖子,所以如果一个帖子有 20 个 cmets,那么我只想返回最后三个。让这有点棘手的是我想在一个查询中完成它,而不是每个博客帖子的“限制 3”查询,这使得呈现包含大量帖子的页面非常查询繁重。

SELECT *
FROM replies
GROUP BY post_id
HAVING COUNT( post_id ) <=3

这个查询符合我的要求,但只返回每条评论中的一条,而不是三条。

【问题讨论】:

    标签: sql mysql database


    【解决方案1】:
    SELECT  l.*
    FROM    (
            SELECT  post_id,
                    COALESCE(
                    (
                    SELECT  id
                    FROM    replies li
                    WHERE   li.post_id = dlo.post_id
                    ORDER BY
                            li.post_id, li.id
                    LIMIT 2, 1
                    ), CAST(0xFFFFFFFF AS DECIMAL)) AS mid
            FROM    (
                    SELECT  DISTINCT post_id
                    FROM    replies dl
                    ) dlo
            ) lo, replies l
    WHERE   l.replies >= lo.replies
            AND l.replies <= lo.replies
            AND l.id <= lo.mid
    

    replies (post_id, id) 上建立索引(按此顺序)将大大改进此查询。

    注意l.replies &gt;= lo.replies AND l.replies &lt;= lo.replies的用法:这是为了使索引可用。

    详情请看我博客中的文章:

    【讨论】:

    • 我肯定需要做一些阅读来弄清楚这里发生了什么。其中一些查询,尤其是 CAST() 超出了我的范围。
    • 0xFFFFFFFF 是一个包含最大可能整数的常量。由于它具有 BINARY 类型,因此 CAST 将其转换为整数。 MID 是给定组的第三个 id,如果没有第三个,则为 MAXINT。
    • 如果你感到困惑,你可以用常量 4294967295 替换整个 CAST(...) 东西 :)
    • 啊,是的,4294967295,现在说得通了。 :)
    • @TheLizardKing:你觉得它不圆吗? :) 如果你确定你的数据库中永远不会有这么大的 ID,你可以使用 4,000,000,000 :)
    【解决方案2】:

    您是否跟踪评论日期?您可以对这些结果进行排序以仅获取 3 个最近的结果。

    【讨论】:

    • 没错,但我需要为每个 post_id 抓取 3 个最新的。如果我有 15 个 cmets 和 3 个帖子,一个帖子 5 cmets,那么我想要一个返回 9 cmets 的查询。每个 post_id 的 3 个最近的 cmets。
    【解决方案3】:

    遵循伊恩·雅各布斯的想法

    声明@PostID int

    select top 3 post_id, comment
    from replies
    where post_id=@PostID
    order by createdate desc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      • 2013-02-21
      • 2012-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多