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 :

HAVING et/ou GROUP BY ?


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 49
    Points
    49
    Par défaut HAVING et/ou GROUP BY ?
    Bonjour,

    je suis perdu ds ma requête ! Ma table est la suivante :

    REF | Date | Code
    REF1 | 27/06/07 | A
    REF2 | 26/06/07 | A
    REF4 | 23/06/07 | C
    REF1 | 22/06/07 | B
    REF1 | 22/06/07 | A
    REF9 | 22/06/07 | A
    REF8 | 22/06/07 | C
    REF6 | 22/06/07 | B
    REF4 | 19/06/07 | A

    je veux les réf distinct & triées par date (desc) pour un code défini :

    REF | date
    REF1 | 27/06/07
    REF2 | 26/06/07
    REF9 | 22/06/07
    REF4 | 19/06/07

    Avant de tester en réel sur ma base (énorme ), pourriez vous me valider ma requête (théorique )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT REF, DATE, CODE 
    From MaTable 
    Having Code="A" 
    Order By Desc Date, REF
    Je suis perdu ds la règle de mon prédictat ou du moins je n'arrive pas à projeter le résultat de ma requête : je risque d'avoir les ref qui confirme Code = A et triées par date desc (OK !) mais vais je avoir des doublons dans mes réfs ? si j'ajoute ? je suis perdu.
    Merci.

  2. #2
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Points : 252
    Points
    252
    Par défaut
    Tu ne dois pas te servir de la clause HAVING pour faire ta sélection. HAVING ne sert que pour faire une sélection sur une valeur issue d'une fnct agrégat (avg, min, max).

    Tu mets plutôt where code="A".

    Et rajoute je pense un distinct (Ref, Date, Code)

  3. #3
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 034
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 034
    Points : 23 779
    Points
    23 779
    Par défaut
    Citation Envoyé par MITCH31
    Avant de tester en réel sur ma base (énorme ), pourriez vous me valider ma requête (théorique )
    Tu peux aussi limiter le nombre de lignes renvoyées par la requête aux n premières lignes, mais la synthaxe dépend du SGBDR.
    C'est pratique pour tester si une requête se comporte comme prévu

    ced

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 49
    Points
    49
    Par défaut
    Rép à ruru9 :
    Non la clause Distinct ne me permet pas d'afficher une ligne pour la ref1 à la date du 27/06/07

    Rép à Ced : c'est hyper pratique de tester une requête qui se comporte comme prévu

  5. #5
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Points : 252
    Points
    252
    Par défaut
    Si tu veux une seule ligne, celle du 27/06 pour la ref 1; tu veux donc l'enregistrement le plus récent pour chaque valeur de Ref et cela pour un groupe donné (d'apres ton champs code).

    Est je bien compris??

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 49
    Points
    49
    Par défaut
    tout à fait ruru9

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 102
    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 102
    Points : 28 387
    Points
    28 387
    Par défaut
    Félicitations à ruru9 qui a compris la question qui n'était pas posée

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 49
    Points
    49
    Par défaut
    C'est vrai ! je pensais l'avoir posé d'une autre façon ! je tenterais d'être plus clair la prochaine fois.
    Sur ce, je vais essayer cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT A.REF, A.DATE, A.CODE
    FROM MaTable A
    WHERE A.CODE = "A" AND DATE = 
    (SELECT MAX(B.DATE) FROM MaTable B WHERE (B.CODE="A" AND A.REF=B.REF))
    ORDER BY A.DATE DESC, A.REF

  9. #9
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Points : 252
    Points
    252
    Par défaut
    Moi je dirais peut etre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Select Ref,Date,Code
    From Matable
    where date=any(select max(date)
                         from Matable where Code ="A"
                         group by Ref)

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 49
    Points
    49
    Par défaut
    Merci Ruru9

    Par contre comment la sous interrogation fait elle le lien avec la première ?
    Je m'explique : je pensais qu'il fallait dire à ma 2nde interrogation que la recherche de la date Maxi concernait la ref de la 1ere interrogation

  11. #11
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Points : 252
    Points
    252
    Par défaut
    En fait la requete mere (jusqu'au second select) donne les champs ref, date et code pour les dates comprises dans la liste de valeurs (d'où le ANY sinon le = suffirait) renvoyée par la sous requete (et qui correspond aux dates maximums par ref de code A).

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 93
    Points : 87
    Points
    87
    Par défaut
    Bonjour,

    J'ai une question sur la requête suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Ref,Date,Code
    FROM Matable
    WHERE date = ANY(    SELECT max(date)
                         FROM Matable WHERE Code ="A"
                         GROUP BY Ref)
    La sous-requête va retourner la date la plus élevée pour chaque référénce ayant le code "A".

    Jusqu'ici tout va bien.

    Mais pour moi, la requête principale va projeter tous les enregistrements possédant une date qui est dans la liste renvoyée par la sous-requête, sans tenir compte de leurs code

    Admettons que l'on a les enregistrements suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Ref   |   Date   |   Code
    ------------------------------
    REF1  | 22/06/07 | A
    REF2  | 22/06/07 | B
    REF1  | 18/06/07 | A
    Ici la sous-requête va renvoyer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Date
    --------
    22/06/07
    Puisque 22/06/07 est la date MAX parmis les enregistrements qui ont comme code "A".

    Mais lorsque la requête va comparer les dates avec la liste renvoyée par la sous-requête alors le résultat sera le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Ref   |   Date   |   Code
    ------------------------------
    REF1  | 22/06/07 | A
    REF2  | 22/06/07 | B
    En effet la requête mère regarde si la date de l'enregistrement analysé est bien dans la liste de ceux renvoyés.
    Or 22/06/07, qui est la date de l'enregistrement qui a pour code B est bien dans la liste renvoyée, donc l'enregistrement sera retenu.

    Si j'ai bien compris le fonctionnement de la requête, je rajouterais donc ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT Ref,Date,Code
    FROM Matable
    WHERE date = ANY(    SELECT max(date)
                         FROM Matable WHERE Code ="A"
                         GROUP BY Ref)
    AND Code = "A"
    Desolé par avance si je me trompe complètement

  13. #13
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Points : 252
    Points
    252
    Par défaut
    Christophe, tu as parfaitement raison il faut rajouter code="A" aussi ds la requete mère. Ton exemple le montre bien!

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 93
    Points : 87
    Points
    87
    Par défaut
    D'accord, merci pour cette réponse

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    88
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 88
    Points : 49
    Points
    49
    Par défaut
    Merci pour vos réponses.
    A priori, les 2 fonctionnent pour mon cas ! Bizarre je lance mes tests pour comprendre....

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Hello,

    Je vais faire comme Christophe_ et y allez de ma petite question (en prévenant aussi que je peux me tromper), car il me semble que je suis déjà tomber sur ce cas de figure et avoir résolu le problème de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT Ref, Date, Code
    FROM Matable
    WHERE Code ="A"
    GROUP BY Ref
    HAVING max(Date) = Date
    Est-ce valide ?

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    490
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 490
    Points : 201
    Points
    201
    Par défaut
    sans trop m'avancer je dirais oui ,

    ça te donne toutes les données du code A groupé par ref, de toutes les date max...n'est ce pas ?

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 93
    Points : 87
    Points
    87
    Par défaut
    Je pense aussi que c'est valide, et ça simplifierait grandement la requête.

    Attendons les retours de MITCH31

  19. #19
    Membre confirmé Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Points : 481
    Points
    481
    Par défaut
    Bonjour,
    J'ai passé une mauvaise nuit et je peux me tromper, mais deux choses me choquent à la lecture de ce fil :
    - La dernière solution, donnée par AlSquire, est syntaxiquement incorrecte
    - Le problème de Mitch31 ne peut-être résolu en sql (i.e. hors fonctions analytiques ou autres) qu'en passant par une sous requête et en liant bien les identifiants de le "REF" de la requête avec celui de la sous requête --> La première solution donnée me parait donc la seule correcte.

  20. #20
    Membre actif
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 310
    Points : 252
    Points
    252
    Par défaut
    En fait, c'est la dernière ligne qui me gêne beaucoup

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HAVING max(date) = date
    Est ce par ce que d'habitude dans la clause HAVING on compare généralement à une constante??

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

Discussions similaires

  1. GROUP BY et HAVING MAX
    Par dragoon83 dans le forum Requêtes
    Réponses: 6
    Dernier message: 11/06/2014, 11h55
  2. regroupement GROUP BY.HAVING et critères
    Par garsflo dans le forum Requêtes et SQL.
    Réponses: 6
    Dernier message: 17/10/2007, 12h11
  3. COUNT, GROUP BY et HAVING
    Par yobogs dans le forum Langage SQL
    Réponses: 2
    Dernier message: 11/10/2007, 13h34
  4. comment traduire un "group by/having" dans une query
    Par cau83 dans le forum Alimentation
    Réponses: 1
    Dernier message: 05/06/2007, 09h05
  5. GROUP BY et HAVING dans un UPDATE
    Par MashiMaro dans le forum Langage SQL
    Réponses: 3
    Dernier message: 26/08/2003, 08h03

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