Langage Manipulation de Données 3 : Aggrégation/Fenêtres/Partitions
2025-10-03
L’algèbre relationnelle pure (σ, π, ⋈) ne sait pas tout calculer.
Certains problèmes aisément solubles par un langage de programmation complet (Python, C, R, …) ne sont pas solubles dans l’algèbre relationnelle pure :
compter. Exemple simple : calculer le nombre de lignes d’une table.
dans une table décrivant une arborescence (une organisation hiérarchisée), déterminer tous les descendants d’un enregistrement.
Possibilité de compter, de faire des moyennes, de trouver un maximum, … en SQL (contrairement à l’algèbre relationnelle “classique”).
Idée
Introduire un opérateur \(Résume()\) qui admet comme arguments une table \(T\) et une suite d’expressions susceptibles de calculer des agrégats : moyenne, somme, comptage, etc.
Proposition de syntaxe :
\(Résume(T, expr_1, ..., expr_k)\) retourne une table \(S\) à une ligne et \(k\) colonnes.
La colonne \(i\) de \(S\) contient l’évaluation de \(expr_i\) sur la table \(T\).
Avertissement
Il n’est pas évident de définir ce que peut être une fonction d’agrégation et un agrégat.
Nous travaillerons à partir d’exemples.
SUM et AVG
nomattribut
Résume(T, SOMME(nomattribut))
se traduit en
ALL et DISTINCT des fonctions d’agrégationCes options sont disponibles pour toutes les fonctions
mais sont surtout utiles pour COUNT :
ALL, option par défaut : toutes les valeurs de la colonne sont utilisées,
DISTINCT : les valeurs doublons ne sont utilisées qu’une fois.
SUM et AVG
FRA (dans le schéma world).Traduction de
Europe et Afrique.Traduction de
MAX, MIN
<nomattribut> dans T :NULL)En statistique : données manquantes prises en compte dans les fonctions d’agrégation.
En SQL : données manquantes ignorées dans les fonctions d’agrégation,
à l’exception de COUNT(*).
Résultat : 10 lignes.
Pourtant, ces données manquantes n’empèchent pas le calcul du maximum sur ces colonnes.
+-------------+------------+
| max_gnpold | max_gnp |
+-------------+------------+
| 2102826.00 | 2133367.00 |
+-------------+------------+
NULL
Avertissement
Que se passe-t-il si, après une éventuelle sélection, toutes les valeurs de du calcul d’agrégat sont NULL ?
La valeur calculée est alors NULL, ce qui signifie “pas de valeur”.
Essayez SELECT MIN(gnpold) FROM country WHERE gnpold IS NULL; !
Avertissement
Les fonctions d’agrégation renvoie un scalaire même sur une table vide.
Pour une table vide, la valeur calculée est NULL.
+-----------+
| urban_pop |
|-----------|
| <null> |
+-----------+
Est-ce cohérent?
Le résultat signifie : “Pour le pays de code ‘zzz’, pas de données”
COUNT
On peut aussi compter le nombre de tuples d’une table :
Note
Options de la fonction COUNT :
* : compte le nombre de lignes dans la table ou la sous-requête, en incluant les valeurs NULL.DISTINCT : sans les doublons et sans les valeurs NULL,ALL : avec les doublons mais sans les valeurs NULL,Si la table est vide, COUNT renvoie 0.
COUNT
retourne 239, le nombre de lignes de la table country.
retournent 192, le nombre de valeurs non NULL de la colonne indepyear.
retourne 88, le nombre de valeurs disctintes et non NULL de la colonne indepyear.
PNB moyen par habitant du continent South America
Résultat : 4372,36
Note
\(10^6\) s’écrit 1e6. On a écrit 1e6*gnp car gnp est exprimé en millions de USD.
ROUND(x,s) effectue un arrondi de x avec s chiffres après la virgule. s négatif accepté.
Note
Les fonctions d’agrégation peuvent s’appliquer à des opérations arithmétiques entre les différents attributs d’un même tuple…
Moyenne des PNB/habitant des pays du continent ‘South America’. A ne pas confondre avec la requête précédente !
Résultat : 3176,44
CASE WHEN ...THEN ... [ELSE ...] END
Dans une fonction d’agrégation, une expression CASE WHEN teste des conditions sur le tuple courant et renvoie la valeur correspondant à la première condition vraie.
Avertissement
Si aucune condition n’est vraie et qu’il n’y pas de clause ELSE, CASE retourne NULL.
+-----------+
| urban_pop |
|-----------|
| 22436673 |
+-----------+
CASE WHEN ...THEN ... [ELSE ...] END
Retourne 203956,54
Retourne 260611,14
CASE WHEN ...THEN ... [ELSE ...] END
SELECT
SUM(CASE
WHEN governmentform LIKE '%Monarchy%' THEN population_COUNTRY
ELSE 0 -- résultat identique si on enlève cette ligne
END) AS pop_monarch,
SUM(CASE
WHEN governmentform LIKE '%Republic%' THEN population_COUNTRY
ELSE 0 -- résultat identique si on enlève cette ligne
END) AS pop_repu
FROM country ;+-------------+------------+
| pop_monarch | pop_repu |
|-------------+------------|
| 519485000 | 5502453700 |
+-------------+------------+
FILTER (WHERE condition)
Avec une clause FILTER, la fonction d’agrégation n’utilise que les tuples vérifiant la condition.
+-------------+------------+
| pop_monarch | pop_repu |
|-------------+------------|
| 519485000 | 5502453700 |
+-------------+------------+
Mise en garde
Il est plus conforme à l’algèbre relationnelle et au SQL d’organiser les données en lignes.
+----------------+------------+
| governmentform | population |
|----------------+------------|
| Monarchy | 519485000 |
|----------------+------------|
| Republic | 5502453700 |
+----------------+------------+
Nom des régions comportant plus de \(15\) pays.
On peut faire plus efficace, gràce à la suite du cours :
GROUP BY
GROUP BY permet de regrouper l’ensemble des résultats d’une requête selon la valeur de certains attributs,
Forme des sous-relations auxquelles on peut appliquer des fonctions d’agrégation (SUM, MAX, …) renvoyant un résultat par sous-relation.
Avertissement
Gestion des valeurs manquantes : les valeurs NULLd’un attribut forment un groupe dans la partition selon celui-ci.
GROUP BY
Calculer la population de chaque continent.
+--------------+----------------------+
| continent | population_continent |
+--------------+----------------------+
|Asia | 3705025700 |
|South America | 345780000 |
|North America | 482993000 |
|Oceania | 30401150 |
|Antarctica | 0 |
|Africa | 784475000 |
|Europe | 730074600 |
+--------------+----------------------+
Important
On peut afficher continent pour chaque groupe parce qu’on a groupé selon cet attribut
GROUP BY
Quel est le gnp moyen, le gnp maximum et le gnp minimum par region sur le continent Europe en milliers de USD par habitant ?
+----------------+---------+---------+---------+
| region | avg_gnp | max_gnp | min_gnp |
+----------------+---------+---------+---------+
|Nordic Countries| 28.00 | 32.66 | 0.00 |
|Western Europe | 25.50 | 37.46 | 22.82 |
|British Islands | 22.94 | 23.12 | 20.11 |
|Southern Europe | 13.91 | 20.90 | 0.72 |
|Baltic Countries| 2.96 | 3.70 | 2.64 |
|Eastern Europe | 2.15 | 5.35 | 0.36 |
+----------------+---------+---------+---------+
GROUP BY
Pour chaque région, indiquer le continent, la région et la population du pays le plus peuplé.
La requête suivante n’est pas correcte
Important
Les attributs présents dans le SELECT doivent impérativement être présents dans le GROUP BY pour s’assurer qu’ils sont communs à tous les tuples de chaque groupe.
WITH pmc AS
(SELECT continent, MAX(population_country) AS pop_max
FROM country
GROUP BY continent)
SELECT c.continent, c.name_country AS country_max_pop, c.population_country AS population
FROM country c JOIN pmc ON c.continent = pmc.continent
WHERE c.population_country = pmc.pop_max
ORDER BY pmc.pop_max DESC;+---------------+----------------------------------------------+------------+
| continent | country_max_pop | population |
+---------------+----------------------------------------------+------------+
| Asia | China | 1277558000 |
| North America | United States | 278357000 |
| South America | Brazil | 170115000 |
| Europe | Russian Federation | 146934000 |
| Africa | Nigeria | 111506000 |
| Oceania | Australia | 18886000 |
| Antarctica | Antarctica | 0 |
| Antarctica | Bouvet Island | 0 |
| Antarctica | South Georgia and the South Sandwich Islands | 0 |
| Antarctica | Heard Island and McDonald Islands | 0 |
| Antarctica | French Southern territories | 0 |
+---------------+----------------------------------------------+------------+
Que fait cette requête ?
WITH
co_urb_rate AS
(
SELECT co.countrycode, co.name_country, co.continent, SUM(ci.population)/(co.population_country::numeric) AS urb_rate
FROM world.country co JOIN world.city ci ON co.countrycode = ci.countrycode
WHERE co.population_country > 0
GROUP BY co.countrycode, co.name_country, co.continent
),
cont_max_ur AS
(
SELECT continent, MAX(urb_rate) AS max_ur
FROM co_urb_rate
GROUP BY continent
)
SELECT
co.continent,
co.name_country,
round(co.urb_rate,2)
FROM co_urb_rate co JOIN cont_max_ur ct ON co.urb_rate = ct.max_ur;Pour chaque continent, elle donne le pays le plus urbanisé avec son taux de population urbaine.
Important
La conversion du diviseur avec ::numeric est importante sinon le résultat est un entier (ici 0 ou 1) car la division entre entiers donne un entier par division euclidienne.
Note
Singapore, Gibraltar et les Cocos Islands ont un taux d’urbanisation supérieur à 1 !
Hypothèse : les origines des statistisques de population sur les villes et les pays ne sont pas les mêmes et les critères utilisés sont différents.
GROUP BY ?Note
L’opération GROUP BY ne renvoie pas une table mais (implicitement) une collection de sous-tables indicées/étiquetées par les valeurs des attributs de groupement.
L’opération GROUP BY ne peut pas s’intégrer dans une algèbre relationnelle, même étendue.
Mise en garde
SQL n’offre pas de moyen d’utiliser le partitionnement effectué par GROUP BY autrement que pour effectuer des calculs d’agrégats et/ou une projection sur les attributs de groupement.
Cette requête n’est pas valide :
Cette requête est valide :
HAVING
La clause HAVING permet de poser une condition portant sur chacune des sous-relations générées par le GROUP BY,
Les sous-relations ne vérifiant pas la condition sont écartées du résultat.
Liste des continents comportant au moins cinq régions.
ORDER BY
La clause ORDER BY permet de trier le résultat de la requête, en fournissant la liste des attributs sur lesquels effectuer le tri et en spécifiant le sens du tri pour chacun d’eux (ASC ou DESC).
Mise en garde
L’ordre par défaut est ASC.
Liste des pays triés par ordre décroissant de population
Avertissement
Que se passe-t-il avec les valeurs nulles ?
Le comportement dépend du serveur. PostgreSQL et Oracle les classent comme plus grandes que toutes les autres. SQL Server (Microsoft), MySQL, SQLite font l’inverse.
WHERE, GROUP BY, HAVING, ORDER BY
Important
WHERE),GROUP BY),HAVING),ORDER BY) .Que fait cette requête ?
Une fonction fenêtre effectue une partition puis un calcul sur le groupe de lignes (“une fenêtre”) auquel la ligne courante appartient.
Note
C’est comparable au type de calcul effectué avec une fonction d’agrégation.
Mais les fonctions de fenêtre permettent de faire des calculs différents de ceux réalisés avec GROUP BY.
Avec GROUP BY, le résultat rassemble les lignes d’un même groupe en une seule.
Avec les fonctions fenêtres, chaque ligne de la table reste présente dans le résultat.
Soit f est une fonction d’agrégation (SUM, AVG, MAX, MIN, COUNT, etc.)
effectue le calcul sur le groupe de lignes auquel appartient la ligne courante après un partitionnement selon attribut.
Ce groupe de lignes est le cadre de la fonction fenêtre pour la ligne courante.
Présenter pour chaque pays dont la région comprend le motif Countries, l’espérance de vie du pays et les espérance de vie maximale et minimale des pays de la région.
+------------------+-----------------+---------------+-----+-----+
| Region | Name of country |Life expectancy| min | max |
+------------------+-----------------+---------------+-----+-----+
| Baltic Countries | Latvia | 68.4 | 68.4| 69.5|
| Baltic Countries | Lithuania | 69.1 | 68.4| 69.5|
| Baltic Countries | Estonia | 69.5 | 68.4| 69.5|
| Nordic Countries | Denmark | 76.5 | 76.5| 79.6|
| Nordic Countries | Finland | 77.4 | 76.5| 79.6|
| Nordic Countries | Faroe Islands | 78.4 | 76.5| 79.6|
+------------------+-----------------+---------------+-----+-----+
Note
Avec des fonctions d’agrégation sur un partitionnement par GROUP BY region, il n’était pas possible d’afficher une ligne par pays.
OVER (...)
Pour calculer ce résultat sans fonctions fenêtres :
On effectue une partition selon la region, une aggrégation par groupe pour calculer min(lifeexpectancy) et max(lifeexpectancy). On obtient une table à trois colonnes.
On calcule une (équi)-jointure avec la table country originelle sur la colonne commune region.
On projette le résultat sur les cinq colonnes pertinentes.
ORDER BY
La clause ORDER BY attribut2 :
PARTITION BY attribut1,attribut2 à la même valeur que dans la ligne courante.ORDER BY
row_number() : fonction d’agrégation qui retourne le numéro de la ligne dans la fenêtre.
Pour les pays d’Asie, lister la région, le nom du pays, le rang du pays dans sa région pour l’espérance de vie et le rang du pays dans sa région pour le PNB par habitant.
SELECT region, name_country,
row_number() OVER (
PARTITION BY region
ORDER BY lifeexpectancy DESC
) AS rk_lifeexpectancy,
row_number() OVER (
PARTITION BY region
ORDER BY gnp / population_country DESC
) AS rk_gnp
FROM world.country
WHERE continent LIKE 'Asi%' and lifeexpectancy IS NOT NULL and gnp IS NOT NULL
ORDER BY region, lifeexpectancy DESC;Avertissement
Dans cette requête, il faut rejeter les valeurs NULL sinon le rang n’aurait pas de sens (ces lignes seraient en tête).
Y-a-t-il une correlation entre les deux rangs ?
|region |name_country |rk_lifeexpectancy|rk_gnp|
|-------------------------|--------------------|-----------------|------|
|Eastern Asia |Macao |1 |3 |
|Eastern Asia |Japan |2 |1 |
|Eastern Asia |Hong Kong |3 |2 |
|Eastern Asia |Taiwan |4 |4 |
|Eastern Asia |South Korea |5 |5 |
|Eastern Asia |China |6 |6 |
|Eastern Asia |North Korea |7 |8 |
|Eastern Asia |Mongolia |8 |7 |
|Middle East |Israel |1 |2 |
|Middle East |Jordan |2 |12 |
|Middle East |Cyprus |3 |5 |
|Middle East |Kuwait |4 |4 |
|Middle East |United Arab Emirates|5 |3 |
|Middle East |Bahrain |6 |6 |
|Middle East |Qatar |7 |1 |
|Middle East |Oman |8 |7 |
|Middle East |Palestine |9 |13 |
|Middle East |Lebanon |10 |9 |
|Middle East |Turkey |11 |11 |
|Middle East |Syria |12 |10 |
|Middle East |Saudi Arabia |13 |8 |
|Middle East |Iraq |14 |17 |
|Middle East |Armenia |15 |16 |
|Middle East |Georgia |16 |14 |
|Middle East |Azerbaijan |17 |15 |
|Middle East |Yemen |18 |18 |
|Southeast Asia |Singapore |1 |2 |
|Southeast Asia |Brunei |2 |1 |
|Southeast Asia |Malaysia |3 |4 |
|Southeast Asia |Vietnam |4 |9 |
|Southeast Asia |Thailand |5 |5 |
|Southeast Asia |Indonesia |6 |8 |
|Southeast Asia |Philippines |7 |6 |
|Southeast Asia |Cambodia |8 |7 |
|Southeast Asia |Myanmar |9 |3 |
|Southeast Asia |Laos |10 |10 |
|Southeast Asia |East Timor |11 |11 |
|Southern and Central Asia|Sri Lanka |1 |4 |
|Southern and Central Asia|Iran |2 |1 |
|Southern and Central Asia|Tajikistan |3 |10 |
|Southern and Central Asia|Uzbekistan |4 |6 |
|Southern and Central Asia|Kyrgyzstan |5 |9 |
|Southern and Central Asia|Kazakstan |6 |2 |
|Southern and Central Asia|India |7 |7 |
|Southern and Central Asia|Maldives |8 |5 |
|Southern and Central Asia|Pakistan |9 |8 |
|Southern and Central Asia|Turkmenistan |10 |3 |
|Southern and Central Asia|Bangladesh |11 |12 |
|Southern and Central Asia|Nepal |12 |13 |
|Southern and Central Asia|Bhutan |13 |14 |
|Southern and Central Asia|Afghanistan |14 |11 |
Avec une clause ORDER BY, une fonction fenêtre SUM() effectue une somme cumulée selon l’ordre choisi.
Calculer, pour chaque pays d’Europe, le pourcentage des PNB supérieur ou égal à celui du pays parmi ceux de sa région.
|region |name_country |pc_sum_gnp|
|----------------|-----------------------------|----------|
|Baltic Countries|Lithuania |47,69 |
|Baltic Countries|Latvia |76,23 |
|Baltic Countries|Estonia |100 |
|British Islands |United Kingdom |94,78 |
|British Islands |Ireland |100 |
|Eastern Europe |Russian Federation |41,91 |
|Eastern Europe |Poland |64,9 |
|Eastern Europe |Czech Republic |73,23 |
|Eastern Europe |Hungary |80,55 |
|Eastern Europe |Ukraine |86,94 |
|Eastern Europe |Romania |92,72 |
|Eastern Europe |Slovakia |95,84 |
|Eastern Europe |Belarus |97,92 |
|Eastern Europe |Bulgaria |99,76 |
|Eastern Europe |Moldova |100 |
|Nordic Countries|Sweden |33,47 |
|Nordic Countries|Denmark |59,2 |
|Nordic Countries|Norway |80,76 |
|Nordic Countries|Finland |98,78 |
|Nordic Countries|Iceland |100 |
|Nordic Countries|Svalbard and Jan Mayen |100 |
|Nordic Countries|Faroe Islands |100 |
|Southern Europe |Italy |57,73 |
|Southern Europe |Spain |85,23 |
|Southern Europe |Greece |91,23 |
|Southern Europe |Portugal |96,49 |
|Southern Europe |Croatia |97,49 |
|Southern Europe |Slovenia |98,48 |
|Southern Europe |Yugoslavia |99,32 |
|Southern Europe |Malta |99,5 |
|Southern Europe |Albania |99,66 |
|Southern Europe |Bosnia and Herzegovina |99,8 |
|Southern Europe |Macedonia |99,88 |
|Southern Europe |Andorra |99,96 |
|Southern Europe |San Marino |99,99 |
|Southern Europe |Gibraltar |100 |
|Southern Europe |Holy See (Vatican City State)|100 |
|Western Europe |Germany |45,65 |
|Western Europe |France |76,13 |
|Western Europe |Netherlands |84,07 |
|Western Europe |Switzerland |89,73 |
|Western Europe |Belgium |95,08 |
|Western Europe |Austria |99,61 |
|Western Europe |Luxembourg |99,96 |
|Western Europe |Liechtenstein |99,98 |
|Western Europe |Monaco |100 |
Il est possible d’ajouter une clause RANGE à une clause ORDER BY pour modifier le cadre de la fenêtre :
On utilise les mots clés UNBOUNDED, PRECEDING, FOLLOWING et CURRENT ROW pour spécifier les bornes de l’intervalle que doit respecter attribut2.
Note
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING : le cadre s’étend à tout le groupe défini par la partition.RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW : le cadre s’étend de la première ligne du groupe défini par la partition à la ligne courante.Calcul d’une moyenne mobile sur l’intervalle [GNP ligne courante - 1000 , GNP ligne courante + 1000]
Avertissement
Les fonctions de fenêtre ne sont autorisées que dans les clauses SELECT et ORDER BY de la requête.
Elles sont interdites ailleurs, par exemple dans les clauses GROUP BY, HAVING et WHERE.
En effet, elles s’exécutent logiquement après le traitement de ces clauses.
Mise en garde
De même, les fonctions de fenêtre s’exécutent après les fonctions d’agrégation habituelles.
Cela signifie qu’il est pertinent d’inclure un appel de fonction d’agrégation dans les arguments d’une fonction de fenêtre, mais pas l’inverse.
Introduits dans SQL avec la mode du Data mining (Fouille de données) dans les années 1990.
Permet de réaliser de facon apparemment simultanée des aggrégations de régularités emboîtées.
Dans le monde des statistiques, lorsqu’on aggrège des comptages de grains différents, on parle de tables de contingences (contingency tables).
Un GROUPING SETS permet d’effectuer simultanément des calculs d’agrégats pour différentes partitions de la table.
Il s’écrit dans la clause GROUP BY avec une liste d’ensemble d’attributs de la forme ((c1,c2), (c1), (c2)).
GROUP BY GROUPING SETS ((c1,c2), (c1), ())
signifie que l’on fera les calculs d’agrégats successivement pour les regroupements selon c1,c2, puis pour les regroupements selon c1, puis sans regroupement.
Dans le résultat, lorsque le partitionnement selon c1 est effectué, la colonne c2 a la valeur NULL (i.e. pas de valeur), ce qui cohérent avec le fonctionnement de GROUP BY.
On suppose que les colonnes c1 et c2 de la table t ne contiennent chacune que 2 valeurs distinctes.
La requête
donne un résultat de la forme :
|c1 |c2 |f |
|------|------|-----|
|x1 |y1 |z1 |
|x1 |y2 |z2 |
|x2 |y1 |z3 |
|x2 |y2 |z4 |
| |y1 |z5 |
| |y2 |z6 |
| | |z7 |
GROUPING SETS
|continent |region |max |
|-------------|---------------|----|
|North America|Caribbean |78,9|
|North America|Central America|75,8|
|North America|North America |79,4|
|North America| |79,4|
|South America|South America |76,1|
|South America| |76,1|
| | |79,4|
ROLLUP ( a, b, c, ... )
est un raccourci pour
GROUPING SETS (
( a, b, c, ... ),
...
( a, b ),
( a ),
( )
)
ROLLUP
+-------------+---------------+----+
|Continent |Region |max |
+-------------+---------------+----+
|North America|Caribbean |78.9|
|North America|Central America|75.8|
|North America|North America |79.4|
|North America| |79.4|
|South America|South America |76.1|
|South America| |76.1|
| | |79.4|
CUBECUBE (a, b, c) est un raccourci pour un GROUPING SETS contenant toutes les parties de (a, b, c), c.a.d
GROUPING SETS (
( )
( a, b, c ),
( a, b ),
( a ),
( b, c ),
( b ),
( a, c ),
( c ),
)
CUBE
|continent |region |governmentform |cnt|max |
|-------------|---------------|-----------------------------|---|----|
| | | |51 |79,4|
|South America|South America |Republic |9 |75,7|
|North America|Central America|Republic |6 |75,8|
|North America|Caribbean |Constitutional Monarchy |8 |75,2|
|North America|Caribbean | |24 |78,9|
|South America|South America | |14 |76,1|
|North America|Central America| |8 |75,8|
|South America| | |14 |76,1|
|North America| | |37 |79,4|
| |Caribbean |Constitutional Monarchy |8 |75,2|
| |South America |Republic |9 |75,7|
| |Central America|Republic |6 |75,8|
| |South America | |14 |76,1|
| |Central America| |8 |75,8|
| |Caribbean | |24 |78,9|
|North America| |Constitutional Monarchy |9 |75,2|
|North America| |Republic |10 |75,8|
|South America| |Republic |9 |75,7|
|North America| |Dependent Territory of the UK|6 |78,9|
| | |Republic |19 |75,8|
| | |Constitutional Monarchy |9 |75,2|
| | |Dependent Territory of the UK|7 |78,9|
SELECT : attributs du résultat (avec agrégations éventuelles)WHERE : condition de sélection indépendante du GROUP BY
HAVING : condition de sélection portant sur les groupesRassembler les données mentionnées dans la clause FROM
Filter les lignes selon la clause WHERE
Regrouper les lignes selon la clause GROUP BY
Filtrer les groupes selon la clause HAVING
Specifier les colonnes du résultat selon la clause SELECT
Trier le résultat final selon la clause ORDER BY
Requêtes SQL : Aggrégation/Fenêtres/Partition

MA15E045 – Bases de Données – L3 MIASHS – UParis Cité
Comment afficher un attribut absent de
GROUP BY?Pour chaque continent, indiquer le nom et la population du (des) pays le(s) plus peuplé(s).
Mise en garde
On ne peut pas utiliser une seule requête puisqu’on veut afficher les pays sans grouper selon les pays. Il faut donc faire les calculs d’agrégats dans une sous-requête.
Préférez les CTEs (ou éventuellement les requêtes imbriquées dans
FROM), plus efficaces que les requêtes imbriquées dansWHEREqui sont ré-exécutées inutilement.