[英]MySQL Limit, Group, and AVG Query
这是给你的一个益智游戏:
我将集群计算的统计信息保存在名为“jobs”的MySQL表中。 每个作业行都有一个执行作业的主机(非唯一),作业执行时间(以秒为单位)和一个唯一的整数作为PK,因此我可以通过订购PK来订购已完成的作业。
截至目前,使用average和group by,我可以找到每个主机在所有已完成作业上的平均执行时间(以秒为单位)。 我想要每个主机最后五个作业的平均时间,而不是平均每个主机的所有执行时间。
有各种各样的操作和分组示例,以及有限制操作的大量示例,但有没有办法在相当简单的MySQL查询中将两者结合起来?
编辑:如果我不清楚它,我想要主机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
MySQL没有任何排名/分析/窗口功能,但支持变量,因此您可以在ROW_NUMBER() OVER (PARTITION BY host ORDER BY execution_time DESC)
获得相同的功能。
先前:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.