Mysql在内连接上获得每组的前5个结果

时间:2012-04-03 04:56:39

标签: mysql group-by inner-join greatest-n-per-group

过去我构建了复杂查询的网站(对我来说),但我认为由于我编程的方式,我应该在构建我的网站之前提出我需要的数据库查询。这样我可以避免重构等,但我没有实际的数据。因此,在我的网站上,用户将发布。然后可以由任何其他用户重新发布该帖子(我称之为“TRICKLE”)。我需要根据重新发布的次数来获取每个标记的前5个帖子。 因此,如果“棒球”是标签而3000名用户有一个带有该标签的帖子,我需要获得重新发布的前5名。 结构:

POSTS
-post_id
-member_id
-tag
-title
-post
-date_posted
-is_active

TRICKLES
-post_id
-member_id
-date_trickled

我认为这是一个问题。

select p.post_id, p.tag, p.title, count(p.post_id) from (
select * from posts p inner join
trickles t on t.post_id=p.post_id
group by p.tag order by count(p.post_id) desc limit 5
) order by p.tag asc

对我而言这是说。 首先(内部查询)获取所有帖子及其相关的涓涓细流(重新发布) 并按标签对它们进行分组,然后按每个帖子的最高排序顺序排列,并将其限制为5。 然后获取id,标签,标题,计数(帖子被涓涓细流的总时间) 并按标签

按字母顺序排序

我认为这会给我数据库中每组的前5个涓涓细流,但对于我来说,很难解决这个问题,对于我而言,没有实际数据,我不会在人们加入并开始发布之前。每当我开始深入思考它时,我觉得我的思绪变得混乱。 根据我的说法,这个查询会让我获得数据库中每个常见“标记”的前5个重新发布吗?我提前很感激!

2 个答案:

答案 0 :(得分:2)

我认为行枚举的这个技巧会对你有所帮助。它有点复杂,但应该正常工作:

select 
    j.tag,
    j.post_id,
    j.title,
    j.cnt
from (
            select
                case when @b <> i.tag then (select @a := 0) end tmp1,
                case when @b <> i.tag then (select @b := i.tag) end tmp2,
                (select @a := @a + 1) num,
                i.*
            from (
                        select
                            p.title,
                            p.post_id, 
                            p.tag, 
                            count(*) cnt
                        from posts p
                        left join tickles t on t.post_id = p.post_id
                        group by 
                            p.post_id, p.tag, p.title
                        order by p.tag, count(*) desc
            ) i
            left join (select @a := 0, @b := '') x on 1=1 
) j
where j.num <= 5

答案 1 :(得分:1)

我建议你看一下这个link。检查一次通过技术