mysql在大多数热门类别中最受欢迎的文章

时间:2014-08-24 13:33:00

标签: 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...

另外,观看文章和类别的次数会很好,但这不是必需的。

我已经尝试过计算所有但没有成功。 问候。

1 个答案:

答案 0 :(得分:2)

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

我已在此处使用一些示例数据测试了下面的查询:

Fidde:

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。

如果你只运行内部部分,可能会有所帮助,请参阅此处的小提琴: 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 |

您可以轻松地排除那时不是&lt; = 5的任何内容(这是上述查询所做的)。