J'ai ce tableau:
6 | 2 9 | 2 1 | 1
Je dois le classer par score desc:
id | score 2 | 4 3 | 4 8 | 4 4 | 3 10 | 3 5 | 2 6 | 2 9 | 2 1 | 1 7 | 1
et obtenir les 3 premières lignes qui commencent avec id
6
Le résultat devrait donc être:
id | score 1 | 1 2 | 4 3 | 4 4 | 3 5 | 2 6 | 2 7 | 1 8 | 4 9 | 2 10 | 3
Est-ce possible? Merci d'avance
3 Réponses :
J'aborderais cela avec un sum ()
cumulatif (disponible dans MySQL 8.0):
select id, score from (select @sm := 0) s cross join (select id, score from mytable order by score desc, id) t order by case when id = 6 then @sm := @sm + 1 end desc, score desc, id limit 3
Les commandes sum ()
enregistrer dans la direction requise; dès que l'enregistrement qui a id = 6
est atteint, la somme prend la valeur 1
. Cela permet de mettre ces enregistrements au top. Le reste consiste simplement à ajouter les critères de tri supplémentaires et à limiter le nombre de résultats.
| id | score | | --- | ----- | | 6 | 2 | | 9 | 2 | | 1 | 1 |
Dans les versions antérieures de mysql, vous pouvez émuler la somme des fenêtres avec une variable utilisateur, comme suit:
select id, score from mytable order by sum(id = 6) over(order by score desc, id) desc, score desc, id limit 3
Démo sur DB Fiddle : mêmes résultats
J'aime ta première solution.
@GordonLinoff: très apprécié ... Merci!
Avec cette table
id score 8 4 4 3 10 3
Et cette sélection
SELECT `id`, `score` FROM (SELECT `id`,`score`,if (id = 8,@scoreid:= @scoreid +1,@scoreid) scoreid From table3, (SELECT @scoreid :=0) s Order by score desc) t1 Where scoreid > 0 LIMIT 3;
vous obtenez
CREATE TABLE table3 (`id` int, `score` int) ; INSERT INTO table3 (`id`, `score`) VALUES (1, 1), (2, 4), (3, 4), (4, 3), (5, 2), (6, 2), (7, 1), (8, 4), (9, 2), (10, 3) ;
J'ai dû le décocher, cela ne fonctionne pas quand j'essaie d'obtenir 5 lignes commençant par id 8, mais la solution @forpas fonctionne
Avec ceci:
| id | score | | --- | ----- | | 6 | 2 | | 9 | 2 | | 1 | 1 |
Voir la démo .
Résultats:
select t.* from tablename t cross join (select * from tablename where id = 6) c where t.score < c.score or (t.score = c.score and t.id >= c.id) order by t.score desc, t.id limit 3
Merci! C'est la meilleure solution
@EduardUnruh vérifie une version modifiée du code où vous ne devez spécifier 6
qu'une seule fois.
Agréable! Mais j'ai une autre question: y a-t-il un moyen de trier le score desc, id desc avant d'obtenir 3 lignes commençant par id 6? J'ai essayé en ajoutant "desc" après t.id et obtenir l'ID 9,6,7 mais ça devrait être 6,5,7
Si je comprends bien, cela fera: sélectionnez t. * À partir de nomtable t jointure croisée (sélectionnez * à partir de nomtable où id = 6) c où t.score
Parfait merci encore !! Les heures de réflexion sur la façon de résoudre mes besoins en ajoutant des tonnes de code inutile avant et après les requêtes sont terminées: D