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 :

comment obtenir la valeur maximale d'une colonne pour chaque groupe


Sujet :

Requêtes MySQL

  1. #1
    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 comment obtenir la valeur maximale d'une colonne pour chaque groupe
    Saluton,
    Je dois être plus vieux ou plus fatigué que je ne le croyais, car je n'arrive pas à me dépétrer de cette requête :
    J'ai une table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE `plafonds` (
      `GRUPO` char(8) NOT NULL default '',
      `ID` char(11) NOT NULL default '',
      `ECHELON` char(2) NOT NULL default '0',
      `INDICE` float(10,6) NOT NULL default '0.000000'
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
    Je souhaite obtenir, pour chaque GROUP GRUPO,ECHELON, l'INDICE maximal.
    J'ai essayé cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT `GRUPO`, `ID`,`ECHELON`,`INDICE`
    FROM `plafonds` 
    GROUP BY GRUPO, ECHELON
    ORDER BY GRUPO, ECHELON DESC, INDICE DESC
    mais l'INDICE retourné n'est pas le maximal de chaque GRUPO, ECHELON.
    Voyez-vous ce qui cloche dans ma requête ?
    Merci.

  2. #2
    Membre expert
    Avatar de TheLeadingEdge
    Inscrit en
    Mai 2005
    Messages
    1 199
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 1 199
    Points : 3 103
    Points
    3 103

  3. #3
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Oui, plus clairement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT `GRUPO`, `ID`,`ECHELON`,MAX(`INDICE`)
    FROM `plafonds` 
    GROUP BY GRUPO, ECHELON
    ORDER BY GRUPO, ECHELON DESC, INDICE DESC

  4. #4
    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
    Hélas, ce n'est pas si simple, telle quelle, la requête me retourne bien la valeur maximale de l'INDICE pour chaque GRUPO,ECHELON.

    Le problème c'est que l'ID appartient bien au GRUPO,ECHELON mais ne correspond pas à la valeur MAX(`INDICE`)

  5. #5
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Il y a 2 possibilités :

    - L'ID est forcément toujours le même pour un couple (GRUPO, ECHELON).
    Dans ce cas-là toutes les colonnes du SELECT doivent se retrouver dans le GROUP BY :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT `GRUPO`, `ID`,`ECHELON`,MAX(`INDICE`)
    FROM `plafonds` 
    GROUP BY GRUPO, ECHELON, ID
    ORDER BY GRUPO, ECHELON DESC, INDICE DESC
    - L'ID varie suivant les lignes pour un même couple (GRUPO, ECHELON).
    A ce moment-là ça ne rime à rien de sélectionner ID dans la requête, en effet MySQL ne sait pas laquelle de ses valeurs choisir et il en prend un aléatoire.

  6. #6
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Autant pour moi je n'avais pas vu l'ID dans la requête.

  7. #7
    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
    Citation Envoyé par Maximilian
    Il y a 2 possibilités :

    - L'ID est forcément toujours le même pour un couple (GRUPO, ECHELON).
    Dans ce cas-là toutes les colonnes du SELECT doivent se retrouver dans le GROUP BY :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT `GRUPO`, `ID`,`ECHELON`,MAX(`INDICE`)
    FROM `plafonds` 
    GROUP BY GRUPO, ECHELON, ID
    ORDER BY GRUPO, ECHELON DESC, INDICE DESC
    - L'ID varie suivant les lignes pour un même couple (GRUPO, ECHELON).
    A ce moment-là ça ne rime à rien de sélectionner ID dans la requête, en effet MySQL ne sait pas laquelle de ses valeurs choisir et il en prend un aléatoire.
    Et il n'y a aucun moyen, quitte à passer par un sub-select ou une requête corrélée ?

  8. #8
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Aucun moyen de quoi ?

    Une requête groupée sur (GRUPO, ECHELON) renvoie 1 ligne par couple (GRUPO, ECHELON), on est d'accord ? Donc ce n'est tout simplement pas pertinent de sélectionner la colonne ID dans une telle requête s'il peut y avoir plusieurs ID par (GRUPO, ECHELON)...

    Je ne sais pas si je me fais comprendre ?

  9. #9
    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
    Je suis assez d'accord sur le principe et le concept. Il n'y aurait donc pas moyen, uniquement par requête SQL, d'obtenir l'identifiant de l'indice le plus élevé pour chaque groupe GRUPO,ECHELON.

    Je l'obtiens en parcourant avec php le résultat de la requête globale, sans clause GROUP BY mais avec ORDER BY, mais cela me semble bien lourd.

    La solution SQL à laquelle je pense maintenant s'appuyerait sur la numérotation des lignes dans une colonne rang calculée par comptage avec retour à 1 pour chaque groupe GRUPO,ECHELON suivant l'ordre GRUPO, ECHELON DESC, INDICE DESC, et une jointure avec la requête GROUP BY filtrée par un HAVING rang=1.

    Mais c'est peut-être finalement aussi gourmand en ressources que le parcours de la requête globale avec php.

    Ce post demeurerait donc irrésolu parce qu'insolvable....Dont acte.

    Merci à tous de votre collaboration.

  10. #10
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Je crois avoir compris où tu veux en venir.

    Essaie ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT `GRUPO` as g, `ID`,`ECHELON` as e, indice
    FROM `plafonds`
    WHERE indice = (
    SELECT MAX(indice) FROM plafonds p WHERE p.GRUPO = g AND p.ECHELON = e)

  11. #11
    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
    Effectivement, je pense que la solution passe par le recours à des variables internes à MySQL.
    Merci encore Maximilian, je teste ça ce soir et je vous tiens au courant.

  12. #12
    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
    Bon, cette dernière requête fonctionne parfaitement, je veux dire qu'elle fournit bien les résultats escomptés.
    Seul problème, le sub-select semble très gourmand et, par rapport à la procédure php de parcours itératif du résultat ordonné sans groupage, les temps de réponses sont prohibitifs (la table ne compte qu'un peu plus de 5000 lignes mais le temps de réponse dépasse la minute).
    Mais tout cela est intellectuellement très satisfaisant. Conceptuellement SQL permet ce genre de requête, après, c'est une question de choix en termes de performances.
    Je vais donc clore ce post.
    Merci encore.

  13. #13
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Je ne sais pas si le CREATE TABLE que tu as donné au début est volontairement minimal, mais il n'y a pas de clé primaire sur ID ni d'index sur indice, grupo ou echelon... Ca pourrait expliquer cela.

  14. #14
    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
    La description de la table était effectivement manipulée pour en simplifier la compréhension car la colonne GRUPO est en réalité la concaténation de trois colonnes indexées qui sont des clés étrangères vers des nomenclatures.
    ID, et ECHELON sont indexés mais pas INDICE.
    Ta remarque est évidemment pertinente, mais je n'ai pas la possibilité de modifier la définition de la table, cette requête n'étant qu'une demande ponctuelle de la hiérarchie, le DBA ne veut évidemment pas en entendre parler.
    Et je lui donne raison, on ne va pas modifier les tables à chaque nouvelle marotte des décideurs, ou alors c'est qu'il y a eu de grosses failles lors de la phase d'analyse.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 11/06/2015, 09h52
  2. Réponses: 2
    Dernier message: 27/06/2014, 10h54
  3. comment remplir les valeurs nulles d'une colonne par des zeros '0'
    Par sinoun dans le forum Développement de jobs
    Réponses: 2
    Dernier message: 21/09/2011, 16h38
  4. Réponses: 2
    Dernier message: 10/06/2009, 10h59
  5. Réponses: 2
    Dernier message: 26/01/2009, 15h38

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