MySQL:由10个最近活跃的用户选择5个操作

时间:2012-11-09 20:01:47

标签: mysql

假设一个名为“activity”的表,其中包含以下列:

whenItHapned datetime,who text,what text

我想在过去一小时内选择10个最近活跃用户的5个最新动作。

到目前为止,我有:

SELECT * FROM activity
JOIN (
    SELECT who FROM activity
    WHERE whenItHappened >= (CURDATE()- INTERVAL 1 HOUR)
    GROUP BY (who)
    ORDER BY whenItHappened DESC
    LIMIT 10
) AS unique_recent_users
ON unique_recent_users.who = activity.who;

这可以很好地选择最近十个最近活跃用户的所有活动。但是,我无法找到一种将其限制为每个用户的最后五个操作的好方法。

如果我在SQL语句的末尾放置一个LIMIT子句,它将只返回五个结果。理想的行为是,如果在过去一小时内有十个用户处于活动状态,则应显示50个操作,每个最近活动的用户都有五个。

我可以通过将PHP用于一个查询来获取最新的10个用户,然后从每个用户执行5个操作,但我不禁想到必须有一些优雅的方式在MySQL本地执行此操作

编辑(通过Darrrrren的链接我找到了这个解决方案,它允许我从所有用户中选择5个最近的操作。我不确定性能会是什么样的,尽管表格得到了放大。)

select whenItHappened, who, what
from activity
where (
   select count(*) from activity as a
   where a.who = activity.who and a.whenItHappened <= activity.whenItHappened
) <= 5;

1 个答案:

答案 0 :(得分:0)

在MySQL中没有办法优雅地做到这一点。一种有效的方法需要自联接:

select a.*
from (SELECT who
      FROM activity
      WHERE whenItHappened >= (CURDATE()- INTERVAL 1 HOUR)
      GROUP BY (who)
      ORDER BY whenItHappened DESC
      LIMIT 10
     ) AS unique_recent_users join
     Activity a
     on unique_recent_users.who = activity.who join
     Activity a2
     on a2.who = a.who and
        a2.whenItHappened >= a.WhenItHappened
group by a.id
having count(*) <= 5

(请注意,这是使用MySQL的隐藏列“功能”来返回group by语句中未包含的列。)

如果您在每个用户的活动表中碰巧有一个计数器,那么您可以使用此计数器获取最近的五个。如果您想要50个最近的活动,无论用户如何,您也可以这样做。而且,如果您使用几乎任何其他数据库,那么排名函数(特别是row_number())将优雅地解决问题。