MySQL obtient la position des lignes dans ORDER BY

Avec la table MySQL suivante:

+-----------------------------+ + id INT UNSIGNED + + name VARCHAR(100) + +-----------------------------+ 

Comment puis-je sélectionner une seule ligne ET sa position parmi les autres lignes de la table, sortingées par name ASC . Donc, si les données de la table ressemblent à ceci, lorsqu’elles sont sortingées par nom:

 +-----------------------------+ + id | name + +-----------------------------+ + 5 | Alpha + + 7 | Beta + + 3 | Delta + + ..... + + 1 | Zed + +-----------------------------+ 

Comment pourrais-je sélectionner la ligne Beta obtenir la position actuelle de cette ligne? L’ensemble de résultats que je recherche serait quelque chose comme ceci:

 +-----------------------------+ + id | position | name + +-----------------------------+ + 7 | 2 | Beta + +-----------------------------+ 

Je peux faire un simple SELECT * FROM tbl ORDER BY name ASC puis énumérer les lignes en PHP, mais il semble inutile de charger un jeu de résultats potentiellement important pour une seule ligne.

Utilisez ceci:

 SELECT x.id, x.position, x.name FROM (SELECT t.id, t.name, @rownum := @rownum + 1 AS position FROM TABLE t JOIN (SELECT @rownum := 0) r ORDER BY t.name) x WHERE x.name = 'Beta' 

… pour obtenir une valeur de position unique. Ce:

 SELECT t.id, (SELECT COUNT(*) FROM TABLE x WHERE x.name <= t.name) AS position t.name FROM TABLE t WHERE t.name = 'Beta' 

... donnera aux cravates la même valeur. IE: S'il y a deux valeurs à la deuxième place, elles auront toutes deux une position de 2 lorsque la première requête donnera une position de 2 à l'une d'elles, et 3 à l'autre ...

C’est la seule façon de penser à:

 SELECT `id`, (SELECT COUNT(*) FROM `table` WHERE `name` <= 'Beta') AS `position`, `name` FROM `table` WHERE `name` = 'Beta' 

Si la requête est simple et que la taille du jeu de résultats renvoyé est potentiellement importante, vous pouvez essayer de la diviser en deux requêtes.

La première requête avec un critère de filtrage restreint juste pour extraire les données de cette ligne, et la deuxième requête utilise COUNT avec la clause WHERE pour calculer la position.

Par exemple dans votre cas

Requête 1:

SELECT * FROM tbl WHERE name = 'Beta'

Requête 2:

SELECT COUNT(1) FROM tbl WHERE name >= 'Beta'

Nous utilisons cette approche dans un tableau avec un enregistrement 2M, ce qui est bien plus évolutif que l’approche d’OMG Ponies.

J’ai un problème très similaire, c’est pourquoi je ne poserai pas la même question, mais je partagerai ici ce que j’ai fait, j’ai également dû utiliser un group by, et passer une commande par AVG. Il y a des étudiants, avec des signatures et socore, et je devais les classer (en d’autres termes, je calcule d’abord l’AVG, puis les ordonne en DESC, et finalement j’ai besoin d’append la position (classer pour moi), donc j’ai fait quelque chose de très similaire à la meilleure réponse ici, avec quelques modifications qui s’adaptent à mon problème):

Je mets enfin la colonne de position (classement pour moi) dans le SELECT externe

 SET @rank=0; SELECT @rank := @rank + 1 AS ranking, t.avg, t.name FROM(SELECT avg(students_signatures.score) as avg, students.name as name FROM alumnos_materia JOIN (SELECT @rownum := 0) r left JOIN students ON students.id=students_signatures.id_student GROUP BY students.name order by avg DESC) t 

La position d’une ligne dans la table représente le nombre de lignes “meilleur” que la ligne ciblée.

Donc, vous devez compter ces lignes.

SELECT COUNT (*) + 1 FROM table WHERE name <'Beta'

En cas d’égalité, la position la plus haute est retournée.

Si vous ajoutez une autre ligne avec le même nom de “Beta” après la ligne “Beta” existante, la position retournée sera toujours 2, car ils partageraient la même place dans la classification.

J’espère que cela aidera les personnes qui chercheront quelque chose de similaire à l’avenir, car je crois que le propriétaire de la question a déjà résolu son problème.

peut être ce dont vous avez besoin est avec la syntaxe add

LIMITE

donc utilisez

 SELECT * FROM tbl ORDER BY name ASC LIMIT 1 

si vous avez juste besoin d’une rangée ..