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