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 :

Pourquoi Select et Group by sont dépendants?


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Inscrit en
    Mai 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 187
    Points : 51
    Points
    51
    Par défaut Pourquoi Select et Group by sont dépendants?
    Bonjour,
    c'est une bête question, mais j'aimerais comprendre pourquoi quand on fait un GROUP BY, tous les attributs du GROUP BY doivent obligatoirement se retrouver dans le SELECT?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Select Un, Deux, Trois
    From Table
    GROUP BY Un, Deux;
    Merci d'avance

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Et qu'est-ce que tu voudrais faire de ta colonne Trois ? Puisqu'elle nes sert pas de critère de regroupement, quelle valeur serait retenue ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre du Club
    Inscrit en
    Mai 2008
    Messages
    187
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 187
    Points : 51
    Points
    51
    Par défaut
    Je ne comprends justement pas pourquoi cette colonne ne me servira à rien...

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Ce n'est pas qu'elle ne servira à rien, c'est qu'elle ne pourra pas être regroupée

    (Re)lis ce document de SQLPro qui explique les regroupements : Groupage, ensembles et sous ensembles
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Le GROUP BY n'est pas appliqué sur la requête elle-même mais sur le résultat de cette requête.

    Ta requete n'est pas bonne. Une bonne requete serait par exemple (elle doit contenir une fonction de regroupement, ici Max() ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Un, Deux, Max(Trois)
    FROM TABLE
    GROUP BY Un, Deux;
    A l'exécution la requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT Un, Deux, Trois
    FROM TABLE
    est exécutée.

    Ensuite sur le résultat de cette requete le regroupement est appliqué selon les champs donnés dans le GROUP BY puis la fonction de regroupement est appliquée sur les autres champs.

    C'est pour cela que
    - Tous les champs du GROUP BY doivent être présent dans le résultat
    - Tous les champs ne faisant pas l'objet d'une fonction de regroupement doivent être inclus dans le GROUP BY

    C'est très schématisé pour l'explication, l'exécution réelle est plus complexe mais revient à ça.
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    C'est pour cela que
    - Tous les champs du GROUP BY doivent être présent dans le résultat
    - Tous les champs ne faisant pas l'objet d'une fonction de regroupement doivent être inclus dans le GROUP BY
    Votre seconde assertion est vraie (aux constantes et valeurs systèmes près), mais pas la première.
    Un exemple simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    With TMP as
    (
    select 2009 as yr, 1 as mth from dual union all
    select 2009      , 2        from dual union all
    select 2009      , 3        from dual
    )
      select yr, count(*)
        from tmp
    group by yr, mth;
     
    YR	COUNT(*)
    2009	1
    2009	1
    2009	1
    J'ai une colonne du GROUP BY qui n'est pas dans le SELECT, et ma requête est parfaitement juste.

  7. #7
    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
    Au risque d'embrouiller alex2746, je dirais que les deux phrases énoncées par sevyc64 sont fausses !

    Quels sont les clients ayant passé plus d'une commande ?
    Sauf erreur de ma part, la requête ci dessous y répond, du point de vue de la norme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT cl.c_id, cl.c_numero, cl.c_nom
    FROM client AS cl
    INNER JOIN commande As cm ON cl.cl_id = cm.cm_id_client
    GROUP BY cl.c_id
    HAVING COUNT(*) > 1
    ORDER BY cl.c_nom
    Le SELECT ne comporte pas de fonction de regroupement ; celle-ci est dans le HAVING.
    Le GROUP BY ne comporte que l'identifiant du client car les autres colonnes du SELECT sont fonctionnellement dépendantes de cet identifiant (ce sont d'autres colonnes de la même table).

    Cependant, la plupart des SGBD refuseront cette requête à cause du GROUP BY ne comprenant pas toutes les colonnes non regroupées.
    MySQL l'autorise mais il prend le risque d'afficher des valeurs au hasard lorsque les colonnes non regroupées du SELECT et ne figurant pas dans le GROUP BY ne sont pas fonctionnellement dépendantes du GROUP BY.

    L'erreur fréquente consisite à vouloir modifier la requête ci-dessus pour obtenir les commandes de ces clients, de la mauvaise façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT cl.c_id, cl.c_numero, cl.c_nom, cm.cm_numero, cm.cm_montant_ht
    FROM client AS cl
    INNER JOIN commande As cm ON cl.cl_id = cm.cm_id_client
    GROUP BY cl.c_id
    HAVING COUNT(*) > 1
    ORDER BY cl.c_nom, cm.cm_montant_ht DESC
    MySQL autorisera cette syntaxe, contrairement à la plupart des autres SGBD, mais affichera des valeurs aléatoires pour le numéro de commande et le montant.

    La bonne requête donnant les commandes des clients ayant passé plus d'une commandes est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT t.c_id, t.c_numero AS Numero_Client, t.c_nom, 
      cm1.cm_numero AS Numero_Commande, cm1.cm_montant_ht
    FROM commande AS cm1
    INNER JOIN (
      SELECT cl.c_id, cl.c_numero, cl.c_nom
      FROM client AS cl
      INNER JOIN commande As cm ON cl.cl_id = cm.cm_id_client
      GROUP BY cl.c_id, cl.c_numero, cl.c_nom
      HAVING COUNT(*) > 1
    ) AS t ON cm.cm_id_client = t.c_id
    ORDER BY t.c_nom, cm1.cm_montant_ht DESC
    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 !

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    Sauf erreur de ma part, la requête ci dessous y répond, du point de vue de la norme
    Non pas du tout, MySQL le permet avec sa règle de dépendance, mais la norme ne le prévoit pas.

  9. #9
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Citation Envoyé par CinePhil
    Au risque d'embrouiller alex2746, je dirais que les deux phrases énoncées par sevyc64 sont fausses !
    ...........
    Cependant, la plupart des SGBD refuseront cette requête à cause du GROUP BY ne comprenant pas toutes les colonnes non regroupées.
    ..........
    La bonne requête donnant les commandes des clients ayant passé plus d'une commandes est la suivante :
    Si mes indications sont effectivement peut-être fausses dans le cas particulier de MySQL, tu confirme qu'elles sont quand même plutot juste pour la pluspart des autres SGBD en conseillant même de les suivre pour l'ensemble des SGBD, y compris MySQL
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  10. #10
    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
    Citation Envoyé par Waldar Voir le message
    Non pas du tout, MySQL le permet avec sa règle de dépendance, mais la norme ne le prévoit pas.
    Voir le chapitre 7 de l'article de Cédric Duprez consacré au GROUP BY dans MySQL.

    Ceci dit, je confirme qu'il est fortement recommandé de mettre dans le GROUP BY toutes les colonnes du SELECT ne faisant pas l'objet d'une fonction d'aggrégation, y compris sous MySQL.
    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 !

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Je l'ai déjà lu.
    Comme le dit l'auteur, ça reste une question d'interprétation de "Dépendance fonctionnelle".

    Seules les équipes de MySQL l'ont interprété ainsi, et pourtant il y a des SGBD dont le crédo est de suivre la norme de très près.

    Ca reste, à mon sens, un facteur d'erreur supplémentaire.

    Mais si je développais avec MySQL, j'utiliserai néanmoins cette fonctionnalité, avec les précautions nécessaires.

Discussions similaires

  1. Réponses: 6
    Dernier message: 26/06/2006, 15h52
  2. selection avec group by mais ne garder que ...
    Par Larson dans le forum Langage SQL
    Réponses: 13
    Dernier message: 22/06/2005, 17h23
  3. Mais pourquoi ... Avec IE les tableaux sont décentrés ?
    Par nebule dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 26/11/2004, 10h04
  4. Selection de Groupes ki ne sont pas sous groupes...
    Par superdada dans le forum Langage SQL
    Réponses: 2
    Dernier message: 23/07/2003, 14h42

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