Cette requête devrait fonctionner.
select * from (
select a.state, a.location_id, C,
@n:=case when @s=a.state then @n+1 else 1 end counter,
@s:=a.state
from (select @s:=null) b, (
select pc.state, b.location_id, COUNT(b.location_id) C
from postcode pc
inner join location_postcode lp on lp.postcode_id=pc.id
inner join business b on b.location_id=lp.location_id
group by pc.state, b.location_id
order by pc.state, C desc
) a
) c
where counter <= 10
J'utilisé les noms de champs qui devraient être faciles à suivre, en supposant ces tableaux existent des relations indiquées:
business M-1 location
location M-M postcode
(expands to) => location 1-M location_postcode M-1 postcode
postcode M-1 state
La requête a beentested avec ces données:
create table business (location_id int);
insert into business select floor(rand()*10);
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
insert into business select floor(rand()*10) from business;
create table location_postcode (location_id int, postcode_id int);
insert into location_postcode select 1,1;
insert into location_postcode select 2,1;
insert into location_postcode select 3,1;
insert into location_postcode select 4,2;
insert into location_postcode select 5,1;
insert into location_postcode select 5,2;
insert into location_postcode select 6,1;
insert into location_postcode select 6,3;
insert into location_postcode select 7,1;
insert into location_postcode select 7,4;
insert into location_postcode select 8,5;
insert into location_postcode select 9,6;
insert into location_postcode select 10,7;
create table postcode (id int, state int);
insert into postcode select 1,1;
insert into postcode select 2,2;
insert into postcode select 3,3;
insert into postcode select 4,4;
insert into postcode select 5,4;
insert into postcode select 6,5;
insert into postcode select 7,5;
qui doesn Ne créez pas assez d'enregistrements pour un "top 10" de chacun, mais vous verrez comment la colonne COUNTER se positionne correctement. Pour voir travailler contre ce petit jeu de données, d'abord laisser ce filtre il
where counter <= 10
pour vérifier la colonne COMPTEUR, puis le réduire à quelque chose comme 2 ou 3, pour afficher uniquement le top 2 ou 3 par État.
Vous aurez besoin d'inclure vos définitions de table si vous voulez que les gens vous aident à créer une requête MySQL – Dancrumb
Si vous utilisez l'exemple des catégories, produits et commandes à la fin, vous pouvez imaginer une définition de table standard. C'est aussi une question conceptuelle sur la façon d'y parvenir. Je suis heureux d'écrire la requête que je n'ai aucune idée de la façon de le structurer sans utiliser l'union. – oak
Étiqueté avec 'most-n-per-group' pour vous guider vers des questions similaires - J'ai vu quelqu'un d'autre le faire (et a pris le commentaire exact! :-). Quoi qu'il en soit, cela aurait été fait avec SQL Server avec 'ROW_NUMBER (... PARTITION ON ...)', il s'agit donc de trouver un (gentil) équivalent MySQL, s'il se termine. –