2010-06-30 4 views
3

Comment puis-je numéroter mes résultats où l'ID le plus bas est # 1 et l'ID le plus élevé est #numberOfResultsMySQL: Comment obtenir un nombre séquentiel avec des lignes?

Exemple: Si j'ai une table avec seulement 3 lignes dedans. dont les ID sont 24, 87, 112, il se retirerait comme ceci:

ID 24 87 112 
Num 1 2 3 

La raison pour laquelle je veux cela, est mon manager veut articles à être numérotées comme Item1, item2, etc. J'ai d'abord fait en sorte qu'elle était l'ID mais il les a vus comme item24, item87, item112. Il n'aime pas du tout cela et veut qu'ils soient comme item1, item2, item3. Personnellement, je pense que cela va mener à des problèmes parce que si vous supprimez et ajoutez des éléments, item2 ne fera pas toujours référence à la même chose et pourrait causer de la confusion pour les utilisateurs. Donc, si quelqu'un a une meilleure idée, j'aimerais l'entendre.

Merci.

+0

Essayez de convaincre votre patron que c'est une mauvaise idée, exactement pour la raison que vous avez mentionné vous-même: que se passe-t-il si un élément est supprimé. – jigfox

+0

Non seulement cela, mais les utilisateurs ne devraient pas être liés à un système de numérotation arbitraire. Je ne montrerais aucune identification sur le front end. S'ils veulent un article, ils devraient savoir son nom. Dans certains cas, les éléments peuvent être très similaires ou les noms peuvent être difficiles à utiliser (systèmes médicaux peut-être), puis un système de numérotation * set * peut être utile, mais il est généralement préférable de cacher ces détails aux utilisateurs. –

Répondre

11

Je suis d'accord avec les commentaires à propos de pas en utilisant un schéma de numérotation comme celui-ci si les numéros vont être utilisés pour autre chose qu'un simple affichage ordonné d'éléments avec des nombres. Si les chiffres vont être liés à quelque chose, alors c'est une très mauvaise idée!

Utilisez une variable, et l'incrément dans la déclaration SELECT:

SELECT 
    id, 
    (@row:[email protected]+1) AS row 
FROM table, 
(SELECT @row:=0) AS row_count; 

Exemple:

CREATE TABLE `table1` (
    `id` int(11) NOT NULL auto_increment, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB 

INSERT INTO table1 VALUES (24), (87), (112); 

SELECT 
    id, 
    (@row:[email protected]+1) AS row 
FROM table1, 
(SELECT @row:=0) AS row_count; 

+-----+------+ 
| id | row | 
+-----+------+ 
| 24 | 1 | 
| 87 | 2 | 
| 112 | 3 | 
+-----+------+ 

Comment ça marche

@row est une variable définie par l'utilisateur. Il est nécessaire de le mettre à zéro avant l'exécution de l'instruction principale SELECT. Cela peut se faire comme ceci:

SELECT @row:=0; 

ou comme ceci:

SET @row:=0 

Mais il est pratique de lier les deux déclarations ensemble. Cela peut se faire en créant une table dérivée, qui est ce qui se passe ici:

FROM table, 
(SELECT @row:=0) AS row_count; 

Le second SELECT obtient réellement exécuté en premier. Une fois cela fait, il est juste un cas de incrémenter la valeur de @row pour chaque ligne récupérée:

@row:[email protected]+1 

La valeur @row est incrémenté à chaque fois qu'une ligne est récupérée.Il générera toujours une liste séquentielle de numéros, quel que soit l'ordre d'accès aux lignes. Donc, c'est pratique pour certaines choses, et dangereux pour d'autres choses ...

+0

Merci, je n'ai jamais vu quelque chose comme '@row: =' avant. Si cela ne vous dérange pas pouvez-vous expliquer ce qui se passe là-bas? –

+1

@John Isaacks: J'ai mis à jour ma réponse avec une explication de comment cela fonctionne. – Mike

+0

merci pour la bonne explication et la réponse. +1 pour ça. Je vais vous marquer comme réponse acceptée parce que vous m'avez donné exactement ce que ma question demandait, mais je vais essayer de voir si je peux obtenir que mon directeur accepte d'autre chose avant de l'implémenter. Merci! –

0

Quel est l'identifiant utilisé? Si c'est seulement pour une consultation rapide et facile, alors c'est bien, mais si vous voulez l'utiliser pour supprimer ou gérer comme vous l'avez mentionné, votre seule option serait d'assigner une nouvelle colonne ID unique pour chaque ligne dans la table. Faire ceci est inutile cependant parce que cela duplique le but de votre colonne d'identification initiale.

2

Il semblerait que ce serait mieux de simplement faire ce numéro dans votre code au lieu d'essayer de trouver une façon compliquée de le faire en utilisant SQL. Lorsque vous faites défiler vos éléments, maintenez simplement la séquence à cet endroit.

0

Mon entreprise avait un défi similaire sur un système CMS qui utilisait un champ de commande pour trier les articles sur la première page du site. Les utilisateurs voulaient une icône "promouvoir, rétrograder" sur laquelle ils pouvaient cliquer pour déplacer un article vers le haut ou vers le bas. Encore une fois, pas idéal, mais la stratégie que nous avons utilisée consistait à construire une fonction de promotion et une fonction de rétrogradation qui identifiait la valeur de tri actuelle par requête, additionnée ou soustraite de la valeur précédente ou suivante, puis définissait la valeur de l'article initialement promu/rétrogradé. Il était également essentiel de concevoir l'insertion d'enregistrement pour définir avec précision la valeur initiale des enregistrements nouvellement ajoutés afin que les insertions n'entraînent pas l'ajout d'une valeur en double. Cela a également été appliqué au niveau DB pour des raisons de sécurité. L'utilisateur n'a jamais été autorisé à entrer directement la valeur du tri, mais à le promouvoir ou le rétrograder via des icônes. Pour être honnête, cela a très bien fonctionné pour l'utilisateur.

Si vous devez emprunter cette route ... ce n'est pas impossible. Mais il y a des dommages au cerveau impliqués ....

Questions connexes