2011-04-14 2 views
0

Je souhaite construire une requête unique (ou aussi peu que possible) pour regrouper un ensemble de données. Donc, étant donné un certain nombre de compartiments, je voudrais retourner les résultats en fonction d'une colonne spécifique.Résultats de requête sur segment basés sur des ensembles égaux de valeur de colonne

donc donné une qual appelé qui est un double qui contient:

90.00 
91.00 
94.00 
96.00 
98.00 
99.00 

Je voudrais pouvoir utiliser une clause GROUP BY avec une fonction comme:

SELECT MIN (score), MAX (score), SUM (score) À partir de la table GROUP BY BUCKETS (score, 3)

Idéalement, cela retournera 3 lignes (regroupant les résultats en 3 compartiments avec un nombre de comptes aussi proche que possible dans chaque groupe possible):

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

Y at-il une fonction qui ferait cela? Je voudrais éviter de retourner toutes les lignes et de déterminer moi-même les segments du seau.

Dave

Répondre

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) 

Serve MySQL n'a pas la fonction d'analyse comme rownum(), donc vous devez utiliser une variable pour l'imiter. Une fois que vous le faites, vous pouvez simplement utiliser la fonction ceil() afin de grouper chaque ligne tot comme vous le souhaitez. J'espère que ça aide malgré mon anglais.

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)) 

ou, avec une seule requête

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

Ah. C'est assez proche mais donné 2 il devrait retourner 2 lignes, 3 il devrait retourner 3 lignes. L'idée est que vous ne savez pas combien de lignes sont dans la table ou la distribution des valeurs dans la colonne. – Dave

+0

S'il vous plaît pardonnez-moi, mais je ne comprends pas. :( –

+0

J'ai ajouté une autre requête, j'espère avoir compris :) –

Questions connexes