[英]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.