php - mysql 最受欢迎类别中最受欢迎的文章

标签 php mysql sql aggregate-functions

我有“文章表”:

id,
category_id

类别表:

id

浏览次数表:

id,
article_id,
ip,

我需要的是 mysql 查询,它将给出 5 个类别,其中文章总浏览次数最多(最常阅读的类别)。每个类别中的附加内容必须是具有最大浏览次数的文章列表(最常阅读该类别中的 5 篇文章)

因此查询应返回类似以下内容:

sport, article1
sport, article2
sport, article3
sport, article4
sport, article5
tv, article6
tv, article7
tv, article8
tv, article9
tv, article10
etc...

此外,如果能够了解文章和类别被观看的次数,那就太好了,但这不是必需的。

我尝试过计算所有内容,但没有成功。 问候。

最佳答案

要在 MySQL 中执行此操作,您必须模仿 row_number() over(按类别分区)功能,否则在其他数据库中可用。

我在这里使用一些示例数据测试了下面的查询:

菲德:

http://sqlfiddle.com/#!9/2b8d9/1/0

查询:

select id, category_id
from(
select x.*,
       @row_number:=case when @category_id=x.category_id then @row_number+1 else 1 end as row_number,
       @category_id:=x.category_id as grp
  from (select art.id, art.category_id, count(*) as num_art_views
          from articles art
          join (select art.category_id, count(*)
                 from view_counts cnt
                 join articles art
                   on cnt.article_id = art.id
                group by art.category_id
                order by 2 desc limit 5) topcats
            on art.category_id = topcats.category_id
          join view_counts cnt
            on art.id = cnt.article_id
         group by art.id, art.category_id
         order by art.category_id, num_art_views desc) x
 cross join (select @row_number := 0, @category_id := '') as r
) x where row_number <= 5

为了澄清一些,这将显示前 5 个类别中的前 5 篇文章。

使用 LIMIT 足以获取前 5 个类别,但要获取每个类别中的前 5 篇文章,您必须使用在每次类别更改时重新启动的变量来模仿其他数据库的 PARTITION BY。

如果您只运行内部部分,这可能有助于理解,请参阅此处的 fiddle : http://sqlfiddle.com/#!9/2b8d9/2/0

此时的输出是:

|        ID | CATEGORY_ID | NUM_ART_VIEWS | ROW_NUMBER |    GRP |
|-----------|-------------|---------------|------------|--------|
| article16 |       autos |             2 |          1 |  autos |
| article14 |      planes |             2 |          1 | planes |
| article12 |       sport |             4 |          1 |  sport |
|  article3 |       sport |             3 |          2 |  sport |
|  article4 |       sport |             3 |          3 |  sport |
|  article1 |       sport |             3 |          4 |  sport |
|  article2 |       sport |             3 |          5 |  sport |
|  article5 |       sport |             2 |          6 |  sport |
| article15 |      trains |             2 |          1 | trains |
| article13 |          tv |             6 |          1 |     tv |
|  article9 |          tv |             3 |          2 |     tv |
|  article6 |          tv |             3 |          3 |     tv |
|  article7 |          tv |             3 |          4 |     tv |
|  article8 |          tv |             3 |          5 |     tv |
| article10 |          tv |             2 |          6 |     tv |

此时您可以轻松排除任何不 <= 5 的内容(这就是上面查询的作用)。

关于php - mysql 最受欢迎类别中最受欢迎的文章,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25472241/

相关文章:

php - 进行数据库搜索并发送电子邮件

php - php 读取 1Gb 文件的内存限制应该是多少?

mysql - 在 MySQL 8 中使用点数据类型和 st_distance_sphere 查找最近的地方

mysql - 无法连接到 targat 机器

PHP/MySQL : Simple timekeeping and update scheme?

php - 使用 SQL 连接对大多数记录进行排序

javascript - 通过网络服务器加载页面,然后加载到客户端?

php - 在没有循环或条件的情况下打印 1 到 1000 - 在 PHP 中

php - 查询以获取关于其发票编号具有相同日期的所有行?

mysql - MYSQL如何让一条SELECT语句显示超过1000条记录?