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 : 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
    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.
    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 !

  3. #3
    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
    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.
    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.

  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 : 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
    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 < ...
    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 !

  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 770
    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 770
    Points : 52 723
    Points
    52 723
    Billets dans le blog
    5
    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 +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

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