我尝试在Perl脚本中执行某些操作,但我想知道是否有更简单,更快捷的方法直接通过SQL执行此操作。
首先,这是表格的摘录,我从中获取值(时间列是时间戳):
| Computer | TIME | CPU |
| Computer-1 | 1418115601 | 67 |
| Computer-2 | 1418115601 | 31 |
| Computer-1 | 1418115601 | 39 |
| Computer-2 | 1418115601 | 39 |
| Computer-1 | 1418115601 | 37 |
| Computer-2 | 1418115601 | 38 |
| Computer-1 | 1418115601 | 54 |
| Computer-2 | 1418115601 | 0 |
| Computer-1 | 1418115601 | 52 |
| Computer-2 | 1418116501 | 28 |
| Computer-1 | 1418116501 | 30 |
| Computer-3 | 1418116501 | 33 |
| Computer-1 | 1418116501 | 23 |
| Computer-2 | 1418116501 | 5 |
| Computer-2 | 1418116301 | 5 |
现在,我在这张表中有500或600K行。我用它来创建图表。我只是从Perl脚本中检索值,然后生成图表但无论如何。事情是这些措施每5分钟采取一次。因此,如果我创建一整天的图表,我将获得288分和#34; ((60/5)* 24)每台电脑。
我的问题是,如果我想为我的图表提供更大的粒度,那么我们只说96分(每15分钟一次),我该怎么做?
在这种情况下,我必须找到一种方法告诉"对于每个相同的ID(在这种情况下是计算机)取你找到的最后3个值(我按日期排序,所以应该没有问题),平均他们,并给我结果"。
问题是我不知道如何做到这一点,而且,TIME列也可能是个问题。他会怎么做?是否有可能确定类似"在对CPU的最后3个值进行平均后,只需让最后一行的TIME填充新的平均行" ?或者实际上我也可以平均时间,这仍然有用......
先谢谢大家:)
编辑:
有些人想要一个输出的例子,我希望这里是: (在这个例子中,我们想象我只有2台计算机和6个值)
按照正常的要求我会有这个
mysql> SELECT Computer, TIME, CPU FROM myTable order by date;
| Computer | TIME | CPU |
| Computer-1 | 1418115601 | 10 |
| Computer-2 | 1418115601 | 30 |
| Computer-1 | 1418115701 | 15 |
| Computer-2 | 1418115701 | 40 |
| Computer-1 | 1418115801 | 15 |
| Computer-2 | 1418115801 | 50 |
| Computer-1 | 1418115901 | 12 |
| Computer-2 | 1418115901 | 50 |
| Computer-1 | 1418116101 | 10 |
| Computer-2 | 1418116101 | 40 |
| Computer-1 | 1418116201 | 11 |
| Computer-2 | 1418116201 | 35 |
我希望最后3个值的平均值具有相同的ID(计算机),所以:
| Computer | TIME | CPU |
| Computer-1 | 1418115801 | 13.33 |
| Computer-2 | 1418115801 | 40 |
| Computer-1 | 1418116201 | 11 |
| Computer-2 | 1418116201 | 41.66 |
答案 0 :(得分:2)
你需要模仿MySQL中没有的分析函数ROW_NUMBER()OVER(PARTITION BY)。你在MySQL中使用变量。
我们对每台计算机的行数进行编号0,1,2,3,4,5,6等。然后我们除以3得到0,0,0,1,1,1,2等。这样我们得到聚合的分组标准:
select computer, max(time), avg(cpu)
from
(
select
@row_number := case when @computer = computer then @row_number + 1 else 0 end as row_number,
@computer := computer as computer,
time,
cpu
from mytable
cross join (select @row_number := -1, @computer := '') as t
order by computer, time
) as t
group by computer, row_number div 3
order by computer, row_number div 3;
我在Pinal Dave的博客中找到了row_number技术:http://blog.sqlauthority.com/2014/03/09/mysql-reset-row-number-for-each-group-partition-by-row-number/