IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Connaître le numéro d'une ligne sans parcourir les précédentes ?


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 2
    Points
    2
    Par défaut Connaître le numéro d'une ligne sans parcourir les précédentes ?
    Bonjour,

    Voilà, alors j'ai une table avec un nombre de points. Et j'affiche les 20 premiers dans un classement.

    Voici en gros les deux champs importants :
    • id : INT PRIMARY AUTO_INCREMENT
    • tokens : INT


    Voici ma reqûete pour afficher dans l'ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM clients WHERE tokens != 0 ORDER BY tokens DESC LIMIT 0,20
    Et je voudrais donner à l'utilisateur sa position dans le classement.

    Problème : plusieurs utilisateurs ont le même nombre de points.

    C'est le serveur SQL qui organise l'ordre dans lequel les utilisateurs sont affichés et l'ordre est fixe il me semble.

    Donc je voudrais savoir comment donner la position exacte de l'utilisateur.

    Est-ce qu'il y aurait une possibilité de faire ça en SQL ? Ou faut il que je fasse un for jusqu'à ce que l'id soit la même ?

    Merci d'avance pour vos réponses.

  2. #2
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut
    Bonjour,

    Pour quel SGBDR ? Pour ceux permettant l'utilisation des fonctions de fenêtrage, c'est très simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id, tokens, RANK() OVER(ORDER BY tokens DESC) as Rank
    FROM clients
    WHERE tokens <> 0;
    Mais voyant le LIMIT 0, 20 et "AUTO_INCREMENT", je suppose que vous êtes sous MySQL, est-ce exact ?

    P.S. On parle de colonnes et non de champs.

  3. #3
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Oui, serveur MySQL, j'ai oublié de le préciser, désolé .
    Et sinon le "!=" c'est juste une habitude, dans la requete c'est <> ou > 0 je ne sais plus, mais qu'importe.

    Par contre, dans votre requête, je ne vois pas comment on peut savoir la position (alias rank) vu qu'on ne précise pas l'id .
    J'aurai mal compris quelque chose ?

  4. #4
    Membre actif Avatar de Jihnn
    Inscrit en
    Décembre 2005
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 330
    Points : 273
    Points
    273
    Par défaut
    Si j'ai bien compris, vous cherchez à obtenir les 20 premiers dans un classement quelconque. Comme il est possible que deux personnes aient le même résultat, ils ont le même rang.

    La fonction de fenêtrage rank() assigne donc un rang à chaque ligne, en partant du plus grand tokens au plus petit. On pourrait donc récupérer facilement les personnes ayant un rang plus petit ou égal à 20 (attention : ça ne signifie pas nécessairement 20 personnes) ou alors savoir le rang d'une personne bien précise.

    Mais comme vous êtes sous MySQL, ça ne fonctionne pas, ce dernier ne supportant pas les fonctions de fenêtrage. Il faudrait donc passer par une solution pour simuler l'effet de rank() et je ne vois pas comment le faire simplement. Je laisse donc les pros du SQL répondre !

  5. #5
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Enfait non, je ne cherche pas à le définir, mais juste à le connaître ^^
    C'est à dire que lorsque j'affiche le classement, je veux pas savoir pourquoi celui là est avant l'autre alors qu'ils ont le même nombres de points mais simplement savoir s'il y a moyen du connaitre le numéro de la ligne.

  6. #6
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Les SGBD travaillent sur des ensembles. S'il n'existe pas d'information permettant de déterminer un ordre précis entre deux lignes, le SGBD peut très bien dans certaines condition vous donner l'une avant l'autre et l'autre avant l'une dans d'autres conditions.

    Dans votre cas, si deux utilisateurs ont le même token, ils auront, au sens du tri ensembliste, le même rang. Ils seront parfaitement à égalité.

    Il faut donc une autre information pour déterminer un classement plus précis. Ca peut être l'ID mais est-ce pertinent de se baser sur un identifiant auto-incrémenté pour déterminer que Paul est avant Jacques, juste parce que Paul a été enregistré avant Jacques dans la table ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    ça donnerait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ... ORDER BY tokens DESC,id ...
    ?

    Merci quand même

  8. #8
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Oui c'est ça, si c'est pertinent que le second critère de classement soit l'ID.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Candidat au Club
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    J'vois bien pour l'affichage... Mais alors comment pour le cas de connaître le rang de l'utilisateur ? Avant je travaillais avec "COUNT(*) WHERE tokens < :var_user_tokens" Mais là ... ?

  10. #10
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 281
    Points : 11 737
    Points
    11 737
    Par défaut
    En supposant que je prenne l'option proposée par Phil, càd trancher les ex-aequo par l'ID :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT C1.ID, COUNT(*) AS Rang
    FROM clients C1
      INNER JOIN clients C2 ON (C1.tokens, C1.ID) <= (C2.tokens, C2.ID)
    WHERE C1.tokens != 0 AND C2.tokens != 0
    ORDER BY C1.tokens DESC, C1.ID DESC
    Antoun
    Expert Essbase, BO, SQL

    La bible d'Essbase, 2ème édition

Discussions similaires

  1. Supprimer une ligne sans décaler les autres
    Par nomade333 dans le forum Conception
    Réponses: 4
    Dernier message: 18/04/2012, 23h43
  2. Connaître l'activité d'une table sans passer les statistiques
    Par tibal dans le forum Adaptive Server Enterprise
    Réponses: 9
    Dernier message: 15/06/2010, 11h43
  3. comment inserer une ligne sans indiquer les colomne
    Par tomy_libre dans le forum Langage SQL
    Réponses: 5
    Dernier message: 16/06/2009, 16h18
  4. supprimer une ligne sans influencer les formules
    Par macpascal dans le forum Excel
    Réponses: 1
    Dernier message: 11/06/2009, 23h23
  5. Insérer une ligne sans modifier les formules
    Par coup dur dans le forum Excel
    Réponses: 2
    Dernier message: 17/03/2008, 11h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo