【问题标题】:Mixing different categories results, ordered by score in MySQL混合不同类别的结果,在 MySQL 中按分数排序
【发布时间】:2011-06-05 18:04:38
【问题描述】:

在我的 PHP 应用程序中,我有一个 mysql 文章表,其中包含以下列:

article_id    articletext    category_id    score

每篇文章都有一个根据它的受欢迎程度计算的分数,并且属于特定类别(大约有 10 个类别可用)

我的问题是:我如何执行一个查询来返回得分最高的文章,同时按类别交替它们,这样如果可能的话,不会连续返回相同类别的文章。 例如,如果得分最高的文章得分:100,则返回集将类似于:

article_id    articletext    category_id    score
-----------------------------------------------------
142           <.....>        5              100
153           <.....>        3              97
119           <.....>        5              99
169           <.....>        2              93
121           <.....>        7              89
197           <.....>        2              92
.
.
.

想到的第一个(简单)解决方案是执行 10 次选择(每个类别 1 次),按分数降序对它们进行排序,然后在 PHP 级别,在每个返回的数据集之间交替,一次选择一个结果,然后将它们组合成一个新数组。

有没有更有效的方法来实现这一点?如果可能的话,在 MySQL 级别

【问题讨论】:

  • 有趣的问题 - 一个有点不正统的要求,但很有趣。纯粹基于 SQL 的解决方案可能很棘手。

标签: php mysql sql-order-by categories


【解决方案1】:

获取前 20 名。如果他们不满足要求,请执行额外查询以获取缺失的部分。您应该能够在查询数和每个返回的行数之间取得一些平衡。

如果你获得了前 100 名,它可能会在 90% 的时间里满足要求,并且比 10 个单独的查询更便宜、更快。

如果是 SQL Server,我可以提供更多帮助...

其实我还有一个想法。每 5 分钟运行一个进程,计算列表并将其缓存在表中。使针对相关表的 DML 使缓存无效,因此在重新填充之前不会使用它(也许一篇文章已被删除)。如果缓存无效,您将退回到即时计算它......并且无论如何都可以使用它来重新填充缓存。

也许可以策略性地更新缓存列表而不是重新计算它。但这可能是一个真正的挑战。

这应该有助于提高查询速度和减少数据库负载。如果您的文章列表过时 5 分钟,这无关紧要。哎呀,即使是 1 分钟也可以。

【讨论】:

    【解决方案2】:

    仅用于学习目的。我做了3个类别的测试。我不知道这个查询如何在大型记录集上运行。

    select * from (
    (select @r:=@r+1 as rownum,article_id,articletext,category_id,score
    from articles,(select @r:=0) as r
    where category_id = 1
    order by score desc limit 100000000) 
    union all
    (select @r1:=@r1+1,article_id,articletext,category_id,score
    from articles,(select @r1:=0) as r
    where category_id = 2
    order by score desc limit 100000000)
    union all
    (select @r2:=@r2+1,article_id,articletext,category_id,score
    from articles,(select @r2:=0) as r
    where category_id = 3
    order by score desc limit 100000000)
    ) as t
    order by rownum,score desc
    

    【讨论】:

      【解决方案3】:

      你的幼稚解决方案正是我会做的。

      【讨论】:

      • 这个问题是每次创建 10 个查询而不是 1 个,而且这个函数很可能在我们的网站上非常(最)频繁地使用,所以这可能会增加很多偷听跨度>
      • 您建议的布局有什么优势?为什么不按分数排序并完成它呢?我会被你描述的那种布局弄糊涂。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-03
      • 1970-01-01
      • 1970-01-01
      • 2013-10-03
      相关资源
      最近更新 更多