MySQL限制、组和平均查询
这里有一个谜题给你: 我将集群计算的数据保存在一个名为“jobs”的MySQL表中。每个作业行都有一个主机,该主机上执行的作业不唯一,作业执行时间以秒为单位,以及一个唯一的整数作为主键,因此我可以通过对主键排序来对完成的作业排序 现在,使用average和GroupBy,我可以找到所有已完成作业中每个主机的平均执行时间(以秒为单位)。我想要的不是平均每个主机的所有执行时间,而是每个主机最后五个作业的平均时间 有各种各样的操作和分组方式的例子,还有很多限制操作的例子,但是有没有办法在一个相当简单的MySQL查询中将两者结合起来呢MySQL限制、组和平均查询,mysql,Mysql,这里有一个谜题给你: 我将集群计算的数据保存在一个名为“jobs”的MySQL表中。每个作业行都有一个主机,该主机上执行的作业不唯一,作业执行时间以秒为单位,以及一个唯一的整数作为主键,因此我可以通过对主键排序来对完成的作业排序 现在,使用average和GroupBy,我可以找到所有已完成作业中每个主机的平均执行时间(以秒为单位)。我想要的不是平均每个主机的所有执行时间,而是每个主机最后五个作业的平均时间 有各种各样的操作和分组方式的例子,还有很多限制操作的例子,但是有没有办法在一个相当简单的
编辑:如果我不清楚,我想要主机1的平均五次执行时间,主机2的平均五次执行时间,等等。我最初的反应是使用LIMIT将平均结果限制为5次,这让我建议:
select a.host, avg(a.execution_time) from (select id, execution_time, host from jobs order by id desc limit 5) a group by a.host;
但很明显,这将平均值限制在最近的5个工作岗位,而不是每个主机最近的5个工作岗位
如果不使用某种存储过程,似乎很难使用LIMIT来限制平均值。这使我考虑使用MySQL变量分配每个作业的每个主机完成顺序或位置。
这是未经检验的,但它所阐述的理论应该是一个很好的起点:
首先,我们应该根据每个职位的主人为其分配一个职位:
select
host,
execution_time,
@current_pos := if (@current_host = host, @current_pos, 0) + 1 as position,
@current_host := host
from
(select @current_host := null, @current_pos := 0) set_pos,
jobs
order by
host,
id desc;
建立位置后,只需选择聚合函数,将结果限制在前5个位置:
select
jt.host,
avg(jt.execution_time)
from
(
select
host,
execution_time,
@current_pos := if (@current_host = host, @current_pos, 0) + 1 as position,
@current_host := host
from
(select @current_host := null, @current_pos := 0) set_pos,
jobs
order by
host,
id desc
) jt
where
jt.position <= 5
group
by host;
请让我知道这是否适合你,或者如果有更多方面我没有考虑。这是一个有趣的问题
我想要主机1的平均五次执行时间,主机2的平均五次执行时间,以此类推
哦。。。在这种情况下,请使用:
SELECT x.host, AVG(x.execution_time)
FROM (SELECT j.pk,
j.host,
j.execution_time,
CASE
WHEN @host != j.host THEN @rownum := 1
ELSE @rownum := @rownum + 1
END AS rank,
@host := j.host
FROM JOBS j
JOIN (SELECT @rownum := 0; @host := '') r
ORDER BY j.host, j.execution_time DESC) x
WHERE x.rank <= 5
GROUP BY x.host
一个小问题;您遇到了与我相同的问题,嵌套查询将只返回五台主机。是的,我看到问题比我最初想象的更复杂。我已经更新了我的解决方案,试图解决这个问题。我也没有运气。我只得到一个结果,但不是平均值。@Rob:根据澄清更新了嗯……到目前为止,我对上述解决方案有一些问题,不过我可能还会继续使用它。
SELECT AVG(j.execution_time) AS avg_last_five_jobs
FROM JOBS j
JOIN (SELECT t.pk
FROM JOBS t
ORDER BY t.pk DESC
LIMIT 5) x ON x.pk = j.pk