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 :

Comprendre le mot-clé HAVING


Sujet :

Langage SQL

  1. #1
    bruce-willis
    Invité(e)
    Par défaut Comprendre le mot-clé HAVING
    Bonjour,

    J'ai déjà utilisé SQL depuis longtemps mais seulement avec des simples requêtes au pir GROUP BY mais pas de HAVING

    Donc, j'essaie ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM methodeContraceptive
    LEFT OUTER JOIN planningfamilial ON ( meth_id = pf_methAdoptId )
    GROUP BY meth_id
    HAVING YEAR( pf_premConsultDate ) = '2010'
    MySQL a réponduocumentation
    #1054 - Unknown column 'pf_premConsultDate' in 'having clause'
    J'ai bien cherché à comprendre mais rien, c'est pour cela que je pose la question ici
    Dernière modification par CinePhil ; 25/02/2010 à 12h27. Motif: Balises codes

  2. #2
    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 : 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 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Pourquoi faire un GROUP BY alors que tu n'utilises pas de fonction de calcul dans le SELECT ?

    HAVING opère sur le résultat du GROUP BY.

    Si je comprends ta requête, là il te faut un simple WHERE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
    FROM methodeContraceptive
    LEFT OUTER JOIN planningfamilial ON meth_id = pf_methAdoptId
    WHERE YEAR( pf_premConsultDate ) = 2010
    Au passage :
    - les parenthèses sont inutiles autour de la condition de jointure ;
    - la fonction YEAR retourne un entier donc inutile de mettre la valeur souhaitée entre apostrophes ;
    - évite le SELECT *.

    Ce qui serait possible avec un regroupement et une restriction sur celui-ci, c'est la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT meth_id, MIN(YEAR(pf_premConsultDate)) AS Annee_mini
    FROM methodeContraceptive
    LEFT OUTER JOIN planningfamilial ON meth_id = pf_methAdoptId
    GROUP BY meth_id
    HAVING MIN(YEAR( pf_premConsultDate )) = 2010
    Elle donnera les méthodes contraceptives intervenues dans le planning familial pour la première fois en 2010.

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 099
    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 099
    Points : 28 392
    Points
    28 392
    Par défaut
    HAVING sert normalement à exprimer une restriction se basant sur le résultat d'une fonction de regroupement.
    Dans le cadre de cette requête, le mot clé HAVING est très mal utilisé et devrait être remplacé par WHERE.
    Quant à ton message d'erreur, il me semble relativement clair... la colonne pf_premConsultDate n'est pas reconnue à ce niveau de la requête.
    Essaye déjà de remplacer HAVING par WHERE et placer la clause GROUP BY à la fin de le requête.

  4. #4
    bruce-willis
    Invité(e)
    Par défaut
    Désolé en fait, il y a un COUNT(*), j'ai seulement essayé de saisir l'erreur

    Donc HAVING nécessite un champ à qui on applique une fonction sql?

  5. #5
    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 : 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 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Principe général de requête de regroupement et de condition sur le regroupement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT les_colonnes_sur_lesquelles_seront_regroupees_les_donnees,
      fonction_de_regroupement(une_colonne) -- COUNT, SUM, MIN, MAX, AVG
    FROM la_table
    GROUP BY les_colonnes_sur_lesquelles_seront_regroupees_les_donnees
    HAVING  fonction_de_regroupement(une_colonne) condition_de_regroupement -- = quelque_chose ou > ou < ...

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 849
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 849
    Points : 52 978
    Points
    52 978
    Billets dans le blog
    6
    Par défaut
    La clause HAVING met en oeuvre un filtre sur les résultats de la requête. Tandis que le filtre WHERE met en oeuvre un filtre sur les données des tables.
    Supposons que la table T compte 1 millions de ligne et que la colonne C comporte la valeur 'toto' dans 10 lignes au plus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM  T 
    HAVING C = 'toto'
    Cette requête oblige à manipuler 1 millions de lignes pour n'en retenir au final que 10
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM  T 
    WHERE  C = 'toto'
    Cette requête ne retient d'emblée que 10 lignes.

    Le coût est sans commune mesure !
    Même si l'écriture avec HAVING est parfaitement légale, elle plombe dramatiquement les performances et empêche d'utiliser les index...

    C'est pourquoi HAVING ne doit servir que lorsque le filtre sur les données est impossible, en particulier dans le cas du filtrage des agrégats, car le calcul résultant d'un agrégat n'est pas connu lors de la lecture de la ligne...

    A +

Discussions similaires

  1. Extraction de mots clés
    Par Olive1808 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 01/02/2016, 20h49
  2. Réponses: 12
    Dernier message: 21/11/2011, 23h48
  3. Réponses: 4
    Dernier message: 18/08/2011, 11h19
  4. Réponses: 2
    Dernier message: 11/04/2011, 10h02
  5. Bien comprendre le mot clé "implements"
    Par hibou107 dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 12/04/2010, 12h53

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