2011-04-14 52 views
0

我想构建一个单一的查询(或尽可能少)来分组数据集。所以给定了一些桶,我想返回基于特定列的结果。基于等值列值查询分段结果

所以给出一列叫做分数这是一个双重包含:

90.00 
91.00 
94.00 
96.00 
98.00 
99.00 

我希望能够使用GROUP BY子句中包含一个函数:

SELECT MIN(分),MAX(得分),SUM(得分)FROM表GROUP BY BUCKETS(得分,3)

理想情况下,这将返回3行(将结果分组到3个桶中,尽可能接近每个组的平均数) ):

90.00, 91.00, 181.00 
94.00, 96.00, 190.00 
98.00, 99.00, 197.00 

是否有一些功能可以做到这一点?我想避免返回所有行并自己计算出存储段。

戴夫

回答

1
create table test (
id int not null auto_increment primary key, 
val decimal(4,2) 
) engine = myisam; 

insert into test (val) values 
(90.00), 
(91.00), 
(94.00), 
(96.00), 
(98.00), 
(99.00); 

select min(val) as lower,max(val) as higher,sum(val) as total from (
select id,val,@row:[email protected]+1 as row 
from test,(select @row:=0) as r order by id 
) as t 
group by ceil(row/2) 

+-------+--------+--------+ 
| lower | higher | total | 
+-------+--------+--------+ 
| 90.00 | 91.00 | 181.00 | 
| 94.00 | 96.00 | 190.00 | 
| 98.00 | 99.00 | 197.00 | 
+-------+--------+--------+ 
3 rows in set (0.00 sec) 

不幸MySQL没有像ROWNUM解析函数(),所以你必须使用一些变量来效仿。一旦你这样做了,你可以简单地使用ceil()函数来按照你喜欢的方式来分组每一行。希望尽管我的英语能够帮助你。

set @r = (select count(*) from test); 
select min(val) as lower,max(val) as higher,sum(val) as total from (
select id,val,@row:[email protected]+1 as row 
from test,(select @row:=0) as r order by id 
) as t 
group by ceil(row/ceil(@r/3)) 

,或者使用单个查询

select min(val) as lower,max(val) as higher,sum(val) as total from (
select id,val,@row:[email protected]+1 as row,tot 
from test,(select count(*) as tot from test) as t2,(select @row:=0) as r order by id 
) as t 
group by ceil(row/ceil(tot/3)) 
+0

啊。这是非常接近,但给2它应该返回2行,3它应该返回3行。这个想法是,你不知道表中有多少行或列中值的分布。 – Dave 2011-04-14 22:10:27

+0

请原谅我,但我不明白。 :( – 2011-04-14 22:29:31

+0

我已经添加了另一个查询,希望我能理解。:) – 2011-04-14 22:58:03