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

SQL Procédural MySQL Discussion :

Somme de nombres limitée


Sujet :

SQL Procédural MySQL

  1. #1
    DC
    DC est déconnecté
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 15
    Points : 11
    Points
    11
    Par défaut Somme de nombres limitée
    Bonjour,

    Je vous explique le contexte de mon problème. Il s'agit d'un système de gestion de tournoi.

    Je rentre dans ma table 't2005', le numero de tounoi, l'id de l'utilisateur et son nombre de points. Pour mon classement final, je cherche à faire la somme que des 4 meilleurs scores de chaque utilisateur.

    Je vois bien comment faire ça en PHP, mais j'aimerais pouvoir le realiser dans ma requete.

    Voici ma requete pour l'instant, elle n'inclus pas les "4 meilleurs scores".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT user,fname,lname,SUM(points) AS points from `t2005` WHERE cat='U9' GROUP BY user ORDER BY points DESC
    J'espere que j'ai été assez clair dans mon explication.

    Merci d'avance

    DC

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT a.user, a.fname, a.lname,SUM(b.points) AS points 
    FROM `t2005` a INNER JOIN `t2005` b ON a.user    = b.user 
                                       AND a.points <= b.points
    WHERE a.cat = 'U9' 
      AND b.cat = 'U9'
    GROUP BY a.user, a.fname, a.lname
    HAVING COUNT&#40;*&#41; = 4
    ORDER BY points DESC
    b.cat = 'U9'est inutile si U9 est une caractéristique du user et non du tournoi
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  3. #3
    Membre expert
    Avatar de Maljuna Kris
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2005
    Messages
    2 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 613
    Points : 3 950
    Points
    3 950
    Par défaut
    Saluton,
    J'espere que j'ai été assez clair dans mon explication.
    Je crains que non.
    Comment pouvons nous savoir ce que tu entends par score ?
    Est-ce la somme des points obtenus par un joueur pour un tournoi ?
    Auquel cas il faudrait faire un regroupement non seulement sur le joueur, mais aussi sur le tournoi, or, nous ne savons rien de la colonne identifiant le tournoi dans la table t2005.
    D'autre part, pour limiter les résultats aux quatre meilleurs pour chaque joueur dans une requête traitant tous les joueurs, je ne vois pas de solution et, s'il en existe une, elle sera tellement gourmande en ressources qu'il vaut laisser à php le soin de s'occuper du traitement procédural du résultat d'une requête plus simple.
    Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
    articles : Comment émuler un tableau croisé [quasi] dynamique
    et : Une énigme mathématique résolue avec MySQL
    recommande l'utilisation de PDO (PHP5 Data Objects)

  4. #4
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut Re: Somme de nombres limitée
    Je ne pense pas que la solution de Médiat marche. En effet, le HAVING COUNT(*)=4 va limiter les résultats aux joueurs ayant exactement 4 scores, ce qui n'est pas ce que l'on veut.

    Tu peux faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT user, fname, lname, points
    FROM `t2005`
    WHERE cat='U9' 
    ORDER BY user, points DESC
    De cette façon, les résultats seront triés d'abord par user et ensuite par point (décroissant). Lors du parcours des résultats, tu ne relèves que les 4 plus hauts scores de chaque utilisateur et tu en fais la somme. (c'est peut-être la solution que tu as envisagée en PHP)

    Sinon, on pourrait peut-être envisager des solutions plus compliquées avec des procédures stockées, reste à savoir si c'est vraiment utile (et si l'environnement d'y prête...)
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  5. #5
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    J'avais, effectivement oublié un bout de la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT a.user, a.fname, a.lname,SUM&#40;b.points&#41; AS points 
    FROM `t2005` a INNER JOIN `t2005` b ON a.user    = b.user 
                                       AND a.points <= b.points 
    WHERE a.cat = 'U9' 
      AND b.cat = 'U9' 
    GROUP BY a.user, a.fname, a.lname, "Identifiant de t2005" 
    HAVING COUNT&#40;*&#41; = 4 
    ORDER BY points DESC
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  6. #6
    DC
    DC est déconnecté
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Merci de vos reponses. Je vais essayer d'etre plus clair:

    - le champ idevent est donc le numero de mon tournoi
    - cat est une categorie de personnes participant au tournoi, il y en a plusieurs par tournoi (ici, c'est U9 pour les moins de 9ans).
    - Enfin, chaque joueur se voit attribué des points à chaque tournoi en fonction de son classement.

    Pour le classement final, on ne retient que les quatres meilleurs scores par joueur que l'on additionne.


    Médiat

    Peut tu m'expliqué le fonctionnement de ta requete. merci, je vais la tester des que je peux.

  7. #7
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    A chaque ligne de t2005 (c'est pourquoi on a besoin de l'identifiant de la ligne), on associe les lignes de tournoi du même user et dont le nombre de points est >=, on totalise les points des lignes associées, mais on ne garde que les lignes qui ont 4 lignes <=.
    Si il y a un risque d'avoir plusieurs fois le même nombre de points, il faudrait compléter la condition AND a.points <= b.points afin de gérer les ex-aequos.

    Exemple
    Si le User 1 a les points suivants (12, 23, 20, 52, 33), les regroupements seront :

    12, {12}
    23, {12, 20, 23}
    20, {12, 20}
    52, {12, 20, 23, 52, 33}
    33, {12, 20, 23, 33}

    Un seul de ce groupes est de taille 4, c'est celui que l'on garde pour faire la somme.
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  8. #8
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    N'empêche, ça m'a l'air tout aussi compliqué...

    <edit>
    Et si un joueur n'a réalisé que 3 scores, comment on fait pour prendre ses 4 meilleurs? Et ben on peut pas !
    </edit>

    Au chapitre des solutions tirées par les cheveux, on a aussi ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT user, fname, lname, SUM&#40;points&#41; AS totalPoints
    FROM t2005 a
     
    WHERE a.cat = 'U9' 
    AND a.points IN 
      &#40;SELECT b.points
       FROM t2005 b
       WHERE b.user = a.user
       ORDER BY b.points DESC
       LIMIT 4&#41;
     
    GROUP BY a.user
    ORDER BY totalPoints DESC
    Mais:
    - On a une requête imbriquée (non supportée par MySQL < 4.1)
    - Question perfs, c'est pas ce qu'il y a de mieux
    - C'est assez crade quand même...
    - Si tu as 5 fois le même score, ton calcul est faux (parce qu'on fait une comparaison sur des points, et non pas sur des clefs primaires)

    D'ailleurs à ce sujet:
    - c'est quoi ta clef primaire dans la table tournoi?
    - dans ta table "t2005", tu as comme champs: user (la clef primaire?), fname et lname. A chaque nouveau score tu rentres à nouveau le nom et le prénom? Ca te choque pas cette redondance d'informations?

    Sinon, j'en reviens à ma solution précédente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT user, fname, lname, points
    FROM `t2005`
    WHERE cat='U9'
    ORDER BY user, points DESC
    Et pour chaque joueur tu ne gardes que le 4 meilleurs scores (par un petit traitement PHP). Comme ça:
    - pas de requêtes imbriquées
    - pas de jointure réflexive avec une condition sur un COUNT
    - juste une requête toute simple avec un ORDER BY que tout le monde comprend (pense au pauvre type qui va devoir maintenir ton appli, stp )
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 10/05/2006, 11h44
  2. [Form] nombre limité de controls ?
    Par ip203 dans le forum Access
    Réponses: 3
    Dernier message: 02/05/2006, 11h18
  3. Réponses: 1
    Dernier message: 02/05/2006, 01h56
  4. un nombre limité de feuilles dans un MDI
    Par elasfer dans le forum MFC
    Réponses: 1
    Dernier message: 14/02/2006, 09h43
  5. select avec un nombre limité de valeurs retournées
    Par felix79 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 23/12/2004, 16h16

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