开发者

Query to Segment Results Based on Equal Sets of Column Value

开发者 https://www.devze.com 2023-02-26 06:19 出处:网络
I\'d like to construct a single query (or as few as possible) to group a data set.So given a number of buckets, I\'d like to return results based on a specific column.

I'd like to construct a single query (or as few as possible) to group a data set. So given a number of buckets, I'd like to return results based on a specific column.

So given a column called score which is a double which contains:

 90.00
 91.00
 94.00
 96.00
 98.00
 99.00

I'd like to be able to use a GROUP BY clause with a function like:

SELECT MIN(score), MAX(score), SUM(score) FROM table GROUP BY BUCKETS(score, 3)

Ideally this would return 3 rows (grouping the results into 3 buckets with as close to equal count in each group as is possible):

 90.00, 91.00, 181.00
 94.00, 96.00, 190.00
 98.00, 99.00, 197.00开发者_JAVA百科

Is there some function that would do this? I'd like to avoid returning all the rows and figuring out the bucket segments myself.

Dave


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:=@row+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)

Unluckily mysql doesn't have analytical function like rownum(), so you have to use some variable to emulate it. Once you do it, you can simply use ceil() function in order to group every tot rows as you like. Hope that it helps despite my english.

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

or, with a single query

select min(val) as lower,max(val) as higher,sum(val) as total from (
select id,val,@row:=@row+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

精彩评论

暂无评论...
验证码 换一张
取 消