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

Développement SQL Server Discussion :

Requête SQL avec GROUP BY [2008]


Sujet :

Développement SQL Server

  1. #1
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut Requête SQL avec GROUP BY
    Bonjour a tous

    Dans ma requete SQL, je souhaiterais ajouter un Group BY Clients.C_Nom
    mais , cela me donne toujours une erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Column 'LnkCliMach.L_DateAchat' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
    Soit il me demande d'ajouter pratiquement tous les champs de la table dans la clause Group By

    Peut on m'expliquer le pourquoi et peut on éviter cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT LnkCliMach.L_DateAchat, LnkCliMach.L_Occasion, TypeMachines.M_TypeMachines, LnkCliMach.L_DesignationMachine, LnkCliMach.L_Actif, 
                                 "LnkCliMach.L_Contrat, LnkCliMach.L_VenteInterne, LnkCliMach.L_IdClient1, LnkCliMach.L_IdClient2, Clients.C_Nom, Clients.C_IdClient, Clients.C_EMail, 
                                 "TypeMachines.M_IdTypeMachines FROM Clients INNER JOIN LnkCliMach ON Clients.C_IdClient = LnkCliMach.L_IdClient1 INNER JOIN 
                                 "TypeMachines ON LnkCliMach.L_IdTypeMachine = TypeMachines.M_IdTypeMachines WHERE (TypeMachines.M_IdTypeMachines = 1)  ORDER BY Clients.C_Nom DESC "
    La Connaissance est comme la joie elle s'accroît en la partageant!

  2. #2
    Membre actif Avatar de ccambier
    Profil pro
    Consultant ERP
    Inscrit en
    Octobre 2006
    Messages
    256
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant ERP

    Informations forums :
    Inscription : Octobre 2006
    Messages : 256
    Points : 267
    Points
    267
    Par défaut
    Bonjour,

    La clause GROUP BY regroupe toutes les lignes de la sélection en combinant leurs valeurs, c'est-à-dire que chaque combinaison différentes de toutes les colonnes retournée dans le SELECT
    Donc pour pouvoir afficher toutes les valeurs regroupées uniquement sur Clients.C_Nom il faut mettre toutes les autres colonnes dans des fonctions d'aggrégation (SUM, AVG, MAX, MIN, ...) ou alors indiquer également dans le Group By les autres colonnes que vous souhaitez afficher.

    Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT LnkCliMach.L_DateAchat, LnkCliMach.L_Occasion, TypeMachines.M_TypeMachines, LnkCliMach.L_DesignationMachine, LnkCliMach.L_Actif, 
    LnkCliMach.L_Contrat, LnkCliMach.L_VenteInterne, LnkCliMach.L_IdClient1, LnkCliMach.L_IdClient2, Clients.C_Nom, Clients.C_IdClient, Clients.C_EMail, 
    TypeMachines.M_IdTypeMachines
    FROM Clients INNER JOIN LnkCliMach 
    ON Clients.C_IdClient = LnkCliMach.L_IdClient1 
    INNER JOIN TypeMachines 
    ON LnkCliMach.L_IdTypeMachine = TypeMachines.M_IdTypeMachines 
    WHERE (TypeMachines.M_IdTypeMachines = 1)  
    GROUP BY LnkCliMach.L_DateAchat, LnkCliMach.L_Occasion, TypeMachines.M_TypeMachines, LnkCliMach.L_DesignationMachine, LnkCliMach.L_Actif, 
    LnkCliMach.L_Contrat, LnkCliMach.L_VenteInterne, LnkCliMach.L_IdClient1, LnkCliMach.L_IdClient2, Clients.C_Nom, Clients.C_IdClient, Clients.C_EMail, 
    TypeMachines.M_IdTypeMachines 
    ORDER BY Clients.C_Nom DESC
    Pour éviter cela il faut savoir exactement le but de regrouper par client dans votre cas, faire une moyenne? faire une Somme?....
    Ensuite se demander si dans cette requête on a besoin d'avoir toutes ces informations (est-ce vraiment nécessaire ?)

    Ce qu'il faut bien comprendre avec le GROUP BY c'est que chaque combinaison de toutes les colonnes affichées cause une rupture.

  3. #3
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Ok, merci bien pour la lumière

    si bien compris, je ne peux pas avoir par exemple :
    un SELECT sur LnkCliMach.L_Occasion sans l'avoir dans le Group By du fait que les données contenue dans le LnkCliMach.L_Occasion vont créer une rupture.

    Mais alors comme la requête ci-dessus ( celle que tu m'as donné ) me donne plusieurs fois le même nom de client ( Clients.C_Nom ) avec des désignation de machines différentes a chaque lignes ( LnkCliMach.L_DesignationMachine), comment puis-je les regrouper sans tenir compte de ces désignations machines et n'avoir qu'une seule ligne contenant le client et sont EMail par ex.
    La Connaissance est comme la joie elle s'accroît en la partageant!

  4. #4
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Points : 4 043
    Points
    4 043
    Par défaut
    Pour rester sur un niveau purement abstrait :

    Un GROUP BY est un regroupement en sous-ensembles. Lorsque tu fais une requête sur une table, tu peux obtenir :
    1. des lignes de résultat qui sont à la même granularité que la table d'origine
    2. une seule ligne qui agrège des calculs d'agrégats. Par exemple SELECT COUNT(*) FROM matable te retourne une seule ligne de résultat
    3. plusieurs lignes de résultats si tu utilise un GROUP BY

    Dans le troisième cas, en utilisant un GROUP BY, tu vas te retrouver avec une ligne par regroupement, regroupement le plus fin de la combinaison de toutes les colonnes que tu mets dans le GROUP BY. C'est comme dans la phrase "je veux savoir le nombre de personnes par étage de mon immeuble", tu vas obtenir autant de nombres que tu as d'étages, par un seul nombre pour tout l'immeuble.

    Or tu ne peux pas dire "je veux savoir le nombre de personnes par étage de mon immeuble, et son prénom", ça n'a pas de sens. Tu ne peux pas demander à SQL Server : "donne moi un sous-total et un détail en même temps". Par contre tu peux lui demander "donne-moi un sous-total et le plus petit prénom par sous-total", ça c'est possible : tu as passé "prénom" dans une fonction d'agrégation qui décide quelle valeur tu veux obtenir dans ce sous-total.
    Rudi Bruchez
    Rudi Bruchez EIRL, solutions MS SQL Server et NoSQL
    LinkedIn - [Outil libre de diagnostic SQL Server : Sql Trismegiste]
    LIVRES : Optimiser SQL Server -
    Microsoft SQL Server 2012 Security Cookbook
    - les bases de données NoSQL

    e-learning : LinkedIn Learning - Pluralsight

  5. #5
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    La c'est le complément précis

    Merci bien de cette explication qui devrait m'aider a l'avenir,
    car proprement dit dans SQL je débute un peut.

    Encore merci a tous les deux
    La Connaissance est comme la joie elle s'accroît en la partageant!

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    En effet, les colonnes qui ne font pas partie d'une fonction d’agrégat doivent être dans le group by, pour une raison somme toute très logique :

    Si vous regroupez vos lignes par la colonne Clients.C_Nom, vous aurez donc une et une seule ligne par Clients.C_Nom distinct. Mais alors quelle données mettre dans cette ligne si un client à plusieurs LnkCliMach.L_DateAchat différentes ?

    Donc :
    - soit vous regroupez également par LnkCliMach.L_DateAchat, et dans ce cas vous aurez une ligne par couple [Clients.C_Nom, LnkCliMach.L_DateAchat] distinct,
    - soit vous utilisez une fonction d'agrégat pour spécifier la valeur de que vous voulez retirer de vos différents LnkCliMach.L_DateAchat (MIN, MAX, ...)

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

Discussions similaires

  1. [MySQL-5.5] Requête SQL avec ORDER BY et GROUP BY
    Par Alexcontact dans le forum Requêtes
    Réponses: 4
    Dernier message: 29/04/2014, 14h27
  2. Réponses: 2
    Dernier message: 17/03/2014, 11h18
  3. Requête SQL avec Group By par semaine
    Par SOPSOU dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 08/07/2013, 22h20
  4. Réponses: 2
    Dernier message: 16/05/2012, 09h48
  5. Requête SQL avec UNION, sum et GROUP BY
    Par Guitariff dans le forum Langage SQL
    Réponses: 6
    Dernier message: 03/12/2006, 13h48

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