HAVING en SQL Oracle : filtrer les groupes efficacement

Découvrez comment utiliser la clause HAVING en SQL Oracle pour filtrer des groupes de données. Syntaxe, exemples pratiques et erreurs à éviter.

Illustration du tutoriel SQL Oracle : HAVING en SQL Oracle : filtrer les groupes efficacement

La clause HAVING en SQL Oracle : filtrer les groupes de données

La clause HAVING en SQL Oracle est un outil indispensable pour filtrer les résultats issus d’un regroupement de données. Contrairement à WHERE qui agit sur les lignes individuelles, HAVING s’applique après l’agrégation réalisée par GROUP BY. Elle permet aux développeurs et analystes de cibler précisément les groupes qui satisfont une condition métier, comme identifier les départements dépassant un budget ou les clients avec un panier moyen élevé.

Publicité

Définition et cas d’usage de HAVING en SQL Oracle

La clause HAVING est utilisée conjointement avec GROUP BY pour poser une condition de filtrage sur un groupe agrégé. Elle intervient après le calcul des fonctions d’agrégation telles que SUM(), COUNT(), AVG(), MIN() ou MAX().

Différence fondamentale entre WHERE et HAVING

Il est crucial de comprendre la distinction entre ces deux clauses :

  • WHERE filtre les lignes avant le regroupement.
  • HAVING filtre les groupes après le regroupement et le calcul des agrégats.

Cas d’usage en entreprise

Dans un contexte professionnel, HAVING est couramment utilisé pour :

  • Identifier les régions dont le chiffre d’affaires dépasse un seuil défini.
  • Lister les produits commandés plus de N fois sur une période donnée.
  • Détecter les employés ayant cumulé plus d’un certain nombre d’heures supplémentaires.
  • Surveiller les comptes bancaires présentant plus de X transactions mensuelles.

Oracle Database, utilisé massivement dans les grandes entreprises, tire pleinement parti de cette clause dans les requêtes analytiques et les tableaux de bord décisionnels.

Syntaxe de la clause HAVING en SQL Oracle

Voici la syntaxe complète d’une requête utilisant HAVING dans Oracle :

SELECT colonne1, fonction_agregation(colonne2)
FROM nom_table
[WHERE condition_sur_lignes]
GROUP BY colonne1
HAVING condition_sur_agregat
[ORDER BY colonne1];

Explication des paramètres essentiels

ÉlémentDescription
SELECTColonnes et agrégats à afficher dans le résultat
FROMTable(s) source(s) des données
WHEREFiltre optionnel appliqué avant le regroupement
GROUP BYColonnes servant de critère de regroupement
HAVINGCondition portant sur un agrégat, appliquée après GROUP BY
ORDER BYTri optionnel des résultats finaux

Ordre d’exécution Oracle : FROMWHEREGROUP BYHAVINGSELECTORDER BY. Respecter cet ordre logique est essentiel pour écrire des requêtes performantes.

Publicité

Exemples pratiques de HAVING en SQL Oracle

Exemple 1 — Départements dont la masse salariale dépasse 50 000 €

Contexte métier : Le service RH souhaite identifier les départements dont la masse salariale totale dépasse 50 000 € afin d’initier une revue budgétaire.

-- Sélection du département et du total des salaires
SELECT
    d.nom_departement,
    SUM(e.salaire) AS masse_salariale_totale
FROM
    employes e
    JOIN departements d ON e.id_departement = d.id_departement
-- Regroupement par département
GROUP BY
    d.nom_departement
-- Filtre : on ne conserve que les départements dépassant 50 000 €
HAVING
    SUM(e.salaire) > 50000
-- Tri décroissant pour faciliter la lecture
ORDER BY
    masse_salariale_totale DESC;

Résultat attendu : Une liste des départements triés par masse salariale décroissante, ne contenant que ceux dont le total dépasse le seuil défini. Oracle calcule d’abord les sommes par département, puis applique le filtre HAVING.

Exemple 2 — Clients ayant passé plus de 5 commandes en 2024

Contexte métier : L’équipe commerciale veut cibler les clients les plus actifs pour leur proposer un programme de fidélité.

-- Nombre de commandes par client sur l'année 2024
SELECT
    c.id_client,
    c.nom_client,
    COUNT(o.id_commande) AS nb_commandes
FROM
    clients c
    JOIN commandes o ON c.id_client = o.id_client
-- Filtre sur l'année AVANT regroupement (rôle de WHERE)
WHERE
    EXTRACT(YEAR FROM o.date_commande) = 2024
-- Regroupement par client
GROUP BY
    c.id_client, c.nom_client
-- Filtre sur l'agrégat : clients avec plus de 5 commandes
HAVING
    COUNT(o.id_commande) > 5
-- Tri par nombre de commandes décroissant
ORDER BY
    nb_commandes DESC;

Point Oracle : La fonction EXTRACT(YEAR FROM date) est native à Oracle et permet d’isoler l’année d’un champ de type DATE ou TIMESTAMP. Le WHERE réduit le volume de données traitées avant le GROUP BY, ce qui améliore les performances.

Erreurs courantes avec HAVING en SQL Oracle

Erreur fréquente : utiliser HAVING sans GROUP BY

Une erreur classique consiste à employer HAVING sans clause GROUP BY. Bien qu’Oracle tolère cette syntaxe dans certains cas (en considérant l’ensemble de la table comme un seul groupe), cela conduit souvent à des résultats inattendus ou à une requête non optimisée.

Code problématique :

-- INCORRECT : HAVING sans GROUP BY explicite
SELECT COUNT(id_commande) AS total_commandes
FROM commandes
HAVING COUNT(id_commande) > 100;

Solution recommandée : Toujours associer HAVING à un GROUP BY explicite pour garantir la lisibilité et la maintenabilité du code.

-- CORRECT : avec GROUP BY explicite
SELECT
    id_client,
    COUNT(id_commande) AS total_commandes
FROM commandes
GROUP BY id_client
HAVING COUNT(id_commande) > 100;

Erreur fréquente : confondre WHERE et HAVING pour les agrégats

Utiliser WHERE avec une fonction d’agrégation provoque une erreur Oracle ORA-00934 : group function is not allowed here.

-- INCORRECT : WHERE ne peut pas filtrer un agrégat
SELECT id_departement, AVG(salaire)
FROM employes
WHERE AVG(salaire) > 3000  -- ORA-00934
GROUP BY id_departement;
-- CORRECT : utiliser HAVING pour filtrer sur un agrégat
SELECT id_departement, AVG(salaire) AS salaire_moyen
FROM employes
GROUP BY id_departement
HAVING AVG(salaire) > 3000;

Résumé : ce qu’il faut retenir sur HAVING en SQL Oracle

Point cléDétail
Rôle de HAVINGFiltrer les groupes après agrégation (GROUP BY)
Différence avec WHEREWHERE filtre les lignes, HAVING filtre les groupes
Fonctions compatiblesSUM(), COUNT(), AVG(), MIN(), MAX()
Ordre d’exécutionAprès GROUP BY, avant ORDER BY
Erreur Oracle couranteORA-00934 si agrégat utilisé dans WHERE
Utilisation sans GROUP BYDéconseillée, même si syntaxiquement acceptée

2 bonnes pratiques Oracle

  1. Combinez WHERE et HAVING : utilisez WHERE pour réduire le nombre de lignes traitées en amont du GROUP BY, et HAVING pour filtrer les agrégats. Cette combinaison améliore significativement les performances sur de grands volumes de données Oracle.
  2. Évitez de recalculer l’agrégat dans HAVING : sur Oracle 12c et versions supérieures, vous pouvez utiliser un alias de colonne dans ORDER BY, mais pas dans HAVING. Répétez l’expression agrégée dans HAVING pour rester compatible avec toutes les versions Oracle.

Aller plus loin avec SQL Oracle

Maintenant que vous maîtrisez la clause HAVING, approfondissez vos compétences en SQL Oracle avec ces sujets complémentaires :

Publicité

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Publicité