Langage Manipulation de Données 3 : Aggrégation/Fenêtres/Partitions
2024-10-04
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 ( \(\sigma(), \pi(), \bowtie(), ...\) ) :
accessibilité dans un graphe non-orienté (qui puis-je contacter dans un réseau social?)
compter : quel est le nombre de lignes d’une table ?
Idée générale
Un opérateur Résume()
qui admet une opérande T
de type table et comme autres arguments une suite d’expressions susceptibles de calculer des agrégats
Résume(T, expr1, ..., exprk)
retourne une table S
à une ligne et k
colonnes
La colonne i
de S
contient l’évaluation de expri
sur la table T
Mise en garde
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 concrets
OLAP
Statistique et Data Science
SELECT
nomattribut
Résume(T, SOMME(nomattribut))
se traduit en
nomattribut
Résume(T, MOYENNE(nomattribut))
se traduit en
Le type des attributs doit être un nombre ou un entier (sinon, impossible de faire des sommes, des moyennes…).
SUM
et AVG
FRA
(dans le schéma world
).Traduction de
South America
Traduction de
MAX
, MIN
maximum des valeurs prises par <nomattribut>
minimum des valeurs prises par <nomattribut>
dans T
Mise en garde
Attention aux valeurs nulles !
NULL = MIN(NULL, 3, 100)
ou 3 = MIN(NULL, 3, 100)
?
Essayez SELECT MIN(gnpold) FROM country;
!
Que se passe-t-il lorsqu’on calcule un agrégat sur une colonne contenant des données manquantes (NULL
) ?
Quelles sont les procédés mis en œuvre en statistique ?
Quels sont les procédés mis en œuvre par PostgreSQL ?
SELECT name_country, gnpold, gnp
FROM country
WHERE continent = 'Europe' AND (gnp IS NULL OR gnpold IS NULL)
name_country | gnpold | gnp
-------------------------------+--------+----------
Andorra | | 1630.00
Bosnia and Herzegovina | | 2841.00
Faroe Islands | | 0.00
Gibraltar | | 258.00
Svalbard and Jan Mayen | | 0.00
Yugoslavia | | 17000.00
Monaco | | 776.00
San Marino | | 510.00
Belarus | | 13714.00
Holy See (Vatican City State) | | 9.00
COUNT
On peut aussi compter le nombre de tuples dans le résultat d’une requête
Nombre de valeurs prises par le résultat
SUM
SUM()
On peut sommer les valeurs contenues dans une colonne numérique
Est-ce cohérent?
CASE WHEN ...THEN ... ELSE ...
SELECT
SUM(CASE
WHEN governmentform LIKE '%Monarchy%' THEN population_COUNTRY
ELSE 0
END) AS pop_monarch,
SUM(CASE
WHEN governmentform LIKE '%Republic%' THEN population_COUNTRY
ELSE 0
END) AS pop_repu
FROM country ;
+-------------+------------+
| pop_monarch | pop_repu |
|-------------+------------|
| 519485000 | 5502453700 |
+-------------+------------+
FILTER (WHERE condition)
SELECT
SUM(population_country) FILTER
(WHERE governmentform LIKE '%Monarchy%') AS pop_monarch,
SUM(population_country) FILTER
(WHERE governmentform LIKE '%Republic%') AS pop_repu
FROM country ;
+-------------+------------+
| pop_monarch | pop_repu |
|-------------+------------|
| 519485000 | 5502453700 |
+-------------+------------+
Nom des régions comportant plus de \(10\) territoires.
Trouver les régions où au moins un pays possède une espérance de vie inférieure à 50
SELECT DISTINCT continent, region
FROM country c
WHERE (
SELECT MIN(d.lifeexpectancy)
FROM country d
WHERE c.region=d.region
) < 50
ORDER BY continent, region;
Continent | Region |
---|---|
Africa | Central Africa |
Africa | Eastern Africa |
Africa | Northern Africa |
Africa | Southern Africa |
Africa | Western Africa |
Asia | Southeast Asia |
Asia | Southern and Central Asia |
North America | Caribbean |
On peut faire plus simple (et plus efficace) dans le case présent
SELECT
DISTINCT continent, region
FROM country c
WHERE c.lifeexpectancy <50
ORDER BY continent, region;
Continent | Region |
---|---|
Africa | Central Africa |
Africa | Eastern Africa |
Africa | Northern Africa |
Africa | Southern Africa |
Africa | Western Africa |
Asia | Southeast Asia |
Asia | Southern and Central Asia |
North America | Caribbean |
Mais si on veut lister les régions où tous les pays ont une espèrance de vie supérieure à 50 ?
Utilisation d’opérateurs arithmétique entre les différents attributs d’un même tuple…
GROUP BY
GROUP BY
permet de regrouper selon la valeur de certains attributs l’ensemble des résults d’une requête
Forme des sous-relations auxquelles on peut appliquer des opérateurs (SUM
, MAX
, …) renvoyant un résultat par sous-relation
Exemple d’utilisation : regrouper les livraisons par numéro de fournisseur et prendre la quantité maximum livrée par fournisseur.
Schéma général
+-------------+---------------------+---------------+
| countrycode | name_country | continent |
|-------------+---------------------+---------------|
| DZA | Algeria | Africa |
| AGO | Angola | Africa |
| ... | | |
| ATA | Antarctica | Antarctica |
| BVT | Bouvet Island | Antarctica |
| ... | | |
| AFG | Afghanistan | Asia |
| ARM | Armenia | Asia |
| ... | | |
| ALB | Albania | Europe |
| AND | Andorra | Europe |
| ... | | |
| AIA | Anguilla | North America |
| ATG | Antigua and Barbuda | North America |
| ... | | |
| ASM | American Samoa | Oceania |
| AUS | Australia | Oceania |
| ... | | |
| ARG | Argentina | South America |
| BOL | Bolivia | South America |
+-------------+---------------------+---------------+
Population maximale par continent
+---------------+------------+
| continent | max |
|---------------+------------|
| Asia | 1277558000 |
| South America | 170115000 |
| North America | 278357000 |
| Oceania | 18886000 |
| Antarctica | 0 |
| Africa | 111506000 |
| Europe | 146934000 |
+---------------+------------+
Les opérateurs (MAX
, SUM
, etc) s’appliquent à chaque groupe de relations.
Dans le schéma world
, quel est le gnp
moyen par region
sur le continent Europe
?
SELECT region,
ROUND(1000 * SUM(gnp)/SUM(population_country),2) AS avg_gnp,
ROUND(MAX(1000* gnp/population_country),2) AS max_gnp,
ROUND(MIN(1000* gnp/population_country),2) AS min_gnp,
MIN(lifeexpectancy) AS min_life_exp
FROM country
WHERE continent = 'Europe'
GROUP BY region
ORDER BY avg_gnp DESC;
region | avg_gnp | max_gnp | min_gnp | min_life_exp |
---|---|---|---|---|
Nordic Countries | 28.00 | 32.66 | 0.00 | 76.5 |
Western Europe | 25.50 | 37.46 | 22.82 | 77.1 |
British Islands | 22.94 | 23.12 | 20.11 | 76.8 |
Southern Europe | 13.91 | 20.90 | 0.72 | 71.5 |
Baltic Countries | 2.96 | 3.70 | 2.64 | 68.4 |
Eastern Europe | 2.15 | 5.35 | 0.36 | 64.5 |
Quel est le sens de cette requête ?
La requête suivante requête n’est pas correcte
Important
Les attributs présents dans le SELECT
sont forcémment présents dans le GROUP BY
.
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 comportent au moins cinq régions.
GROUP BY
et calcul sur les tablesNote
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 de mémoriser le résultat d’un GROUP BY
avant d’effectuer des agrégations ou une projection sur les attributs de groupement.
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 (ascendan ou descendant)Liste des pays triée par ordre décroissant de population
Que fait cette requête ?
SELECT continent, region, MIN(c.lifeexpectancy)
FROM country c
GROUP BY continent, region
HAVING MIN(c.lifeexpectancy) < 50
ORDER BY continent, region ;
Continent | Region | max | min |
---|---|---|---|
Africa | Central Africa | 65.3 | 38.3 |
Africa | Eastern Africa | 72.7 | 37.2 |
Africa | Northern Africa | 75.5 | 49.8 |
Africa | Southern Africa | 51.1 | 39.3 |
Africa | Western Africa | 76.8 | 41.3 |
Asia | Southeast Asia | 80.1 | 46.0 |
Asia | Southern and Central Asia | 71.8 | 45.9 |
North America | Caribbean | 78.9 | 49.2 |
Une fonction fenêtre effectue un calcul sur un (sous)-ensemble de lignes de la table qui sont liées à la ligne courante.
Note
C’est comparable au type de calcul effectué avec une fonction d’agrégation.
Mais les fonctions de fenêtre ne regroupement pas les lignes en une seule ligne de sortie.
Au contraire, les lignes conservent leurs identités distinctes.
En coulisses, la fonction de fenêtre est capable d’accéder à plus que la ligne actuelle du résultat de la requête.
Dans le schéma world
, présenter pour chaque pays dont la région comprend le motif Countries
, l’espérance de vie, l’espérance de vie maximale et minimale dans 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 |
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.
SELECT region, name_country, lifeexpectancy,
rank() OVER (
PARTITION BY region
ORDER BY lifeexpectancy DESC
)
FROM country
WHERE region LIKE '%Countries'
ORDER BY region, lifeexpectancy DESC
LIMIT 6 ;
Region | Name of country | life expectancy | rank |
---|---|---|---|
Baltic Countries | Estonia | 69.5 | 1 |
Baltic Countries | Lithuania | 69.1 | 2 |
Baltic Countries | Latvia | 68.4 | 3 |
Nordic Countries | Svalbard and Jan Mayen | 1 | |
Nordic Countries | Sweden | 79.6 | 2 |
Nordic Countries | Iceland | 79.4 | 3 |
SELECT
region, name_country,
sum(gnp) OVER (
PARTITION BY region
ORDER BY gnp
)
FROM country c
WHERE region LIKE '%Europe'
LIMIT 6;
Region | Name Country | Sum |
---|---|---|
Eastern Europe | Moldova | 1579.00 |
Eastern Europe | Bulgaria | 13757.00 |
Eastern Europe | Belarus | 27471.00 |
Eastern Europe | Slovakia | 48065.00 |
Eastern Europe | Romania | 86223.00 |
Eastern Europe | Ukraine | 128391.00 |
Mise en garde
Les fonctions de fenêtre ne sont autorisées que dans la liste SELECT
et la clause 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.
Pour chaque continent, afficher les trois pays ayant l’espérance de vie à la naissance la plus élevée
WITH ...
et les CTEsAfficher le pays le plus peuplé
Afficher le pays le plus peuplé
Afficher les 10 pays les plus peuplés
name_country |continent |population_country|
------------------+-------------+------------------+
China |Asia | 1277558000|
India |Asia | 1013662000|
United States |North America| 278357000|
Indonesia |Asia | 212107000|
Brazil |South America| 170115000|
Pakistan |Asia | 156483000|
Russian Federation|Europe | 146934000|
Bangladesh |Asia | 129155000|
Japan |Asia | 126714000|
Nigeria |Africa | 111506000|
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).
ROLLUP
ROLLUP
and CUBE
are special cases of GROUPING SETS
GROUPING SETS
(suite)CUBE
|Continent |Region |Governmentf |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|
region |governmentform |cnt|max |
---------------+--------------------------------------------+---+----+
Caribbean | | 24|78.9|
Caribbean |Constitutional Monarchy | 8|75.2|
Caribbean |Dependent Territory of the UK | 5|78.9|
Caribbean |Republic | 4|73.4|
... | | | |
|Republic | 19|75.8|
|Constitutional Monarchy | 9|75.2|
|Dependent Territory of the UK | 7|78.9|
|Federal Republic | 5|77.1|
|Overseas Department of France | 3|78.3|
...
SELECT <attributs> -- les colonnes de la table résultat
FROM <relations> -- la/les table/s qui émettent les données
[WHERE <condition> ] -- filtre
[GROUP BY <attributs de partitionnement> -- découpage en groupes
[HAVING <condition>]] -- filtrage des groupes
[ORDER BY <critere>] -- trier
SELECT
: attributs du résultat (avec agrégats éventuels)WHERE
: condition de sélection indépendante du GROUP BY
HAVING
: condition de sélection portant sur les groupesAvis
Toutes les requêtes SQL contiennent une combinaison de ces clauses. Retenez au moins cela!
Rassembler 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
MA15Y030 – Bases de Données – L3 MIASHS – UParis Cité