【问题标题】:Select N records for each category and order by X为每个类别选择 N 条记录并按 X 排序
【发布时间】:2010-09-30 16:10:31
【问题描述】:

我有一个包含博客文章的数据库表。我想在主页上显示每个类别的一个(或多个)帖子,例如按日期排序。

所以我的帖子表如下所示:id | title | description | cat | filename | date

如何创建这样的查询?我曾想过使用 group-by 或 subselect,但我不确定这是否对性能有好处...该表有大量记录。

【问题讨论】:

    标签: sql mysql greatest-n-per-group ranking


    【解决方案1】:

    MySQL支持分析函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE...),但您可以使用变量模拟这些函数。

    如果您想要 N 条最新的博文:

    SELECT x.id,
           x.title,
           x.description,
           x.cat,
           x.filename,
           x.date
      FROM (SELECT bp.id,
                   bp.title,
                   bp.description,
                   bp.cat,
                   bp.filename,
                   bp.date,
                   CASE 
                     WHEN bp.cat = @category THEN @rownum := @rownum + 1
                     ELSE @rownum := 1
                   END AS rank,
                   @category := bp.cat
              FROM BLOG_POSTS bp
              JOIN (SELECT @rownum := 0, @category := NULL) r
          ORDER BY bp.cat, bp.date DESC) x
     WHERE x.rank <= N
    

    如果您希望排名 1 是最早的博文,请将 ORDER BY 更改为:

    ORDER BY bp.cat, bp.date
    

    【讨论】:

    • @Mark Byers:也谢谢你!所以,我需要添加这样的东西吗?按 x.date DESC 排序
    【解决方案2】:

    使用更现代的 SQL,使用 CTE 和 Windows 函数(在 PostgreSQL 9.3 中测试,但我怀疑它也适用于最新版本的 MySQL),每个类别显示 2 个标题:

    WITH b AS
      (SELECT title, cat, row_number() OVER (PARTITION BY cat) as rn FROM BLOGS)
    SELECT title, cat FROM b WHERE rn <= 2;
    

    【讨论】:

      猜你喜欢
      • 2019-01-17
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多