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

Requêtes MySQL Discussion :

Requète de tri selon plusieurs critères


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut Requète de tri selon plusieurs critères
    Bonsoir,

    J'ai une requète qui me permet d'établir un classement d'un concours de pronostics (à noter qu'il y a plusieurs filtre selon que l'on chosisse le classement annuel, mensuel ...)

    Pour faire simple ma première table contient la date du match et ma seconde table contient les champs suivants : id_user,id_match,pts

    Actuellement j'utilise le code ci-dessous pour afficher mon classement annuel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT table_match.date, table_pronos.id_user, SUM( pts ) AS sumpts, 
    FROM table_match
    INNER JOIN table_pronos ON table_match.id = table_pronos.id_match
    GROUP BY id_user
    ORDER BY sumpts DESC
    En cas d'égalité au classement je souhaiterais trier sur le nombre de score exact ( dont le champ "point" est égale à 2)
    Je ne sais pas trop comment m'y prendre pour que ma requète ne soit pas trop complexe.

    Merci d'avance pour votre aide

  2. #2
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    salut,

    pour le filtre c'est juste un where qui joue sur la date à rajouter

    ton problème:
    • faire cette requête pour déjà obtenir le classement...
    • pour chaque valeur du classement qui apparait plus d'une fois reclasser par nombre de pts=2 qu'à chaque personne


    la solution est de rajouter une colonne avec une somme du nombre de valeur de pts qui vaut 2 et de compléter le classement par elle

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT table_match.date, table_pronos.id_user, SUM( pts ) AS sum1, sum(if(pts=2,1,0)) as sum2
    FROM table_match
    INNER JOIN table_pronos ON table_match.id = table_pronos.id_match
    GROUP BY id_user
    ORDER BY sum1,sum2 DESC

    je pense que ça devrait marcher

    pour ce qui est du filtre, tu construis ta requête coté php (le plus simple) en rajoutant le filtre qui va bien si besoin en utilisant les fonctions sur les dates par exemple pour extraire le mois ou autre...

    si tu veux pas polluer ton php avec du sql et rendre les deux bien séparé, tu peux faire des procédures stockées qui contiendront chacune la requête voulue... ça donne une meilleur performance et isolation php/mysql...

  3. #3
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Le GROUP BY est incomplet : valeur aléatoire sur table_match.date dans le SELECT.

    Mais tu dis qu'il faut ajouter un WHERE sur la date alors la date peut être unique mais ce WHERE ne figure pas dans ta requête !

  4. #4
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    Merci Eric, c'est exactement le résultat que j'attendais

    Mon classement est juste un peu plus long à s'afficher mais ce n'est pas bien grave il me fallait une solution pour départager les éventuels exaequo.

    Encore merci

  5. #5
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    comme je l'ai dit cinephil... le where c'est s'il veut faire un filtre pour un mois ou autre... ça il peut faire les différentes versions seul, c'est pas dur...

    la requête de base sert pour l'année vu ce qu'il décrit...

    exacte pour le group by... qui devrait être:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    group by table_match,id_user

    je m'étais focalisé sur son problème... mais avec un gentil mysql très permissif ça passe... il semble que si tu cites pas la colonne mysql la prenne en compte dans l'ordre d'apparition... ce qui explique que sa requête marchait...

    je sais

    par contre si ton problème est résolu ça serait bien de le passer en résolu gregtix...

  6. #6
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    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 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    il semble que si tu cites pas la colonne mysql la prenne en compte dans l'ordre d'apparition...
    Si tu fais ce genre de requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT a.col1, b.col2, SUM(b.col3)
    FROM a
    INNER JOIN b ON a.col1 = b.col1
    GROUP BY a.col1
    Avec la plupart des SGBD, elle sera refusée car toutes les colonnes du SELECT ne faisant pas l'objet d'une fonction de groupage doivent figurer dans le GROUP BY.

    MySQL l'accepte mais, s'il n'y a pas dépendance directe de b.col2 par rapport à a.col1, c'est à dire s'il peut y avoir plusieurs valeurs de b.col2 pour un a.col1, alors MySQL donnera pour b.col2 la première valeur qu'il trouvera. Même pas forcément une valeur en association avec celle de a.col1 !

    Contrairement à ce que tu sembles vouloir dire, MySQL ne va pas ajouter tout seul les colonens manquantes dans le GROUP BY.

  7. #7
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    je sais bien qu'elle serait refusée... ce qui est normal...

    c'est qui est pire que ce que je pensais...

    bref d'où le fait de bien écrire son group by pour éviter des résultat inattendu...

  8. #8
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    Concernant ma requète elle est effectivement un peu plus complexe mais la solution proposée me permet d'afficher le résultat attendu.

    Je suis cependant confronté à un autre problème dans un cas un peu particulier car je dois ajouter des points provenant d'une autre table.

    Actuellement je fais cette opération en 2 étapes, la première requète sur laquelle vous venez de m'aider et une seconde pour récupérer les points bonus.

    Suite à ma première requète je récupère le résultat dans un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    while($row = mysql_fetch_array($result_points))
    {
    	$tab_tt[$y][0]=$row['id_user'];
    	$tab_tt[$y][2]=$row['sumpts'];
    	$tab_tt[$y][3]=$row['nbperfect'];
    	$y++;
    }
    Ensuite je dois ajouter les éventuels points bonus (résultat de ma seconde requète)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    while($row = mysql_fetch_array($result_bonus))
    {
    	for($i = 0; $i <= count($tab_tt); $i++)
    	{
    		if (isset($tab_tt[$i][1]) && $tab_tt[$i][1]==$row['id_user'])
    		{
    			$tab_tt[$i][2]+=$row['sumbonus'];
    		}
    	}
    }
    Mon souci c'est que je n'arrive plus à trier mon tableau multidimensionnel. Le but étant de trier tout d'abord sur le nombre de points total puis en cas d'égalité sur le nombre de "score exact" (correspondant à $tab_tt[$y][3])

    Merci d'avance pour votre aide

  9. #9
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    Personne pour me donner un petit coup de main ... peut-être que je n'ai pas été suffisamment clair dans mon explication ?

  10. #10
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    pourquoi tu les rajoutes pas avant?

  11. #11
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    Ce serait probablement la solution la plus simple mais je ne vois pas comment faire ma requète sql sur ces différentes tables.

    Ma première table contient les champs suivants : id_user,id_match,pts
    Je suis obligé de faire une jointure sur ma table match pour récupérer la date du match et la journée de championnat (cela me permet d'effectuer des filtres sur le mois, la journée ..)

    Ma table bonus contient les champs journee,id_user,pts_bonus
    Le champ commun avec la table match c'est la journée, car les bonus sont attribués à la fin de chaque journée.

    Bref je ne sais pas si j'ai été très clair mais n'arrivant pas à faire une requète unique j'avais privilégié 2 requètes distinctes.

  12. #12
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    jointures...

  13. #13
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    J'y ai bien pensé mais je n'arrive pas à m'en sortir

    Faudrait-il que je fasse un autre SELECT dans ma requète actuelle ?

  14. #14
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    comme on le répète souvent, sans toutes les billes, les vraies tables, etc... tu risques de ne pas avoir le résultat voulu...

    quand on maitrise pas le sujet on pas pas le niveau d'abstraction pour "simplifier"

    impossible de te répondre simplement sans savoir comment tu calcules le points supplémentaire et quelles règles tu te donnes pour les ajouter donc aux points précédemment calculés (hors classement, à part, etc...)...

    si chaque joueur a systématiquement un bonus calculé pour chaque jour tu peux faire un inner join (sinon un "left join" serait mieux je pense ici) sur ta table bonus par rapport à id_user et ajouter le contenu de pts_bonus à SUM( pts ) dans le select...

  15. #15
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    Je comprends parfaitement, je vais tenter de mettre un exemple du contenu de chaque table (j'ai supprimé les champs inutiles)

    Table match

    id_match journee date
    1 J1 07/08/2011 20:00
    2 J1 07/08/2011 20:00
    3 J2 14/08/2011 20:00
    4 J2 14/08/2011 20:00

    Tables pronos

    id_user id_match pts
    1 1 1
    1 2 0
    1 3 1
    1 4 0
    2 1 0
    2 2 1
    2 3 0
    3 1 3
    3 2 0
    3 3 3

    Table bonus

    journee id_user pts_bonus
    J1 1 1
    J1 2 0
    J1 3 3
    J2 1 3
    J2 2 0
    J2 3 1

    Pour chaque journée il y a donc plusieurs pronostics par contre il n'y a qu'une attribution de point bonus. Pour que je puisse ensuite ajuster le classement avec mes filtres (par journée, par mois, par année) je ne pense pas qu'il soit judicieux d'ajouter directement les points bonus.

    L'idéal serait d'avoir le résultat dans un tableau contenant les champs suivants : id_user,journée,sum_pts_journee,point_bonus

    Rappel de la requète actuelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT table_match.date, table_pronos.id_user, SUM( pts ) AS sumpts, SUM(IF(pts=3,1,0)) AS nbperfect,
    FROM table_match
    INNER JOIN table_pronos ON table_match.id = table_pronos.id_match
    GROUP BY id_user
    ORDER BY sumpts DESC,nbperfect DESC
    Je ne sais pas si c'est plus clair avec ces exemples.

  16. #16
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    la seule question à te poser c'est ce que tu fais de tes points bonus...

    est-ce qu'ils servent au classement oui ou non?
    est-ce qu'ils doivent se cumuler aux points normaux ou apparaitre à part?

    leur mise à jour étant donc fait une fois par jour par une requête à part... et son résultat mis dans la table bonus...

    une fois que tu figes ta problématique tout en découle simplement

  17. #17
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    Est-ce qu'ils servent au classement oui ou non? OUI

    Est-ce qu'ils doivent se cumuler aux points normaux ou apparaitre à part? ils doivent être cumulés avec les autres points

    Les points bonus sont renseignés automatiquement dans la table bonus lors de la mise à jour du dernier match composant la journée.

  18. #18
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    donc il suffit de rajouter la jointure par rapport à l'id_user sur bonus et dans le select ajouter juste la valeur rapatrié par elle au calcul des points...

    essaye... ici utilise un "left join bonus on" pour ta jointure...

  19. #19
    Futur Membre du Club
    Inscrit en
    Septembre 2009
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Septembre 2009
    Messages : 33
    Points : 6
    Points
    6
    Par défaut
    Je crois que je vais repartir de zéro et regarder quelques tutaux sur les jointures car je ne m'en sors pas

  20. #20
    Membre expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Points : 3 295
    Points
    3 295
    Billets dans le blog
    1
    Par défaut
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT m.date, m.id_user, SUM( pts )+pts_bonus AS sumpts, SUM(IF(pts=3,1,0)) AS nbperfect,
    FROM table_match m
    INNER JOIN table_pronos ON table_match.id = table_pronos.id_match
    left join bonus b on b.id_user=b.id_user
    GROUP BY m.id_user
    ORDER BY sumpts DESC,nbperfect DESC

    ça ferait pas ce que tu veux?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [AC-2010] Requête suppression selon plusieurs critères
    Par stsym dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 18/01/2013, 06h01
  2. [MySQL] Trouver un article selon plusieurs critères de tri
    Par HAbroc dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 24/05/2012, 09h58
  3. [V6] Tris selon plusieurs critères
    Par AD1983 dans le forum Webi
    Réponses: 1
    Dernier message: 02/11/2011, 12h03
  4. Tri Liste d'objet selon plusieurs critéres
    Par missd12 dans le forum Langage
    Réponses: 4
    Dernier message: 06/07/2010, 10h15
  5. [HASHING] Trie selon plusieurs critères
    Par hush dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 24/07/2006, 07h54

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