L3 Info : SGBD
 
◃  Ch. 10 SQL : DQL (Algèbre relationnel et SQL)  ▹
 

Mécanisme de fenêtrage (windowing)

  • Mécanisme miroir de l'agrégation :
    • Avec l'agrégation on produit des résultats calculés par groupes préétablis via GROUP BY
    • Avec le fenêtrage on produit des résultats pour chaque ligne avec des calculs réalisés sur des groupes contextuels
  • Parmi les fonctions dédiées (fonctions analytiques), on retrouve les fonctions d'agrégations et bien d'autres : SUM, AVG, COUNT, MIN, MAX, RANK, DENSE_RANK, ROW_NUMBER, LAG, LEAD, ...
  • Le mécanisme est utilisé dans la clause SELECT (comme une sélection de colonne)
  • Syntaxe générale : <fonction analytique> OVER ( [PARTITION BY <colonnes>] [ORDER BY <colonnes>] [ROWS | RANGE <fenêtre>] )
  • La clause PARTITION BY définit les sous-groupes considérés pour chaque ligne (comme un GROUP BY local)
  • La clause ORDER BY permet de trier l'ordre des lignes dans chaque partition produite
  • La clause ORDER BY affecte le fonctionnement de la fonction qui devient cumulative et pas globale
  • La clause ROWS/RANGE définit la fenêtre de lignes voisines considérées dans le calcul
  • Exemple élémentaire : affichage pour chaque département de la population totale de sa région
    SELECT col_nom, col_region, 
       SUM(col_population) OVER (PARTITION BY col_region)
    FROM collectivite;
    +--------------------+----------+-------+
    |col_nom             |col_region|sum    |
    +--------------------+----------+-------+
    |Haut-Rhin           |Alsace    |1843053|
    |Bas-Rhin            |Alsace    |1843053|
    |Landes              |Aquitaine |3206137|
    |Pyrénées-Atlantiques|Aquitaine |3206137|
    |Lot-et-Garonne      |Aquitaine |3206137|
    |Dordogne            |Aquitaine |3206137|
    |Gironde             |Aquitaine |3206137|
    |Cantal              |Auvergne  |1343964|
    ...
    +--------------------+----------|-------+
    • conserve autant de lignes que de départements
    • La fonction analytique (ici SUM) s'applique sur chaque ligne à la totalité de la partition
  • Exemple avec tri sur les lignes de chaque partition (ici les noms de départements)
    SELECT col_nom, col_region, 
       SUM(col_population) OVER (PARTITION BY col_region ORDER BY col_nom)
    FROM collectivite;
    +--------------------+----------+-------+
    |col_nom             |col_region|sum    |
    +--------------------+----------+-------+
    |Bas-Rhin            |Alsace    |1094439|
    |Haut-Rhin           |Alsace    |1843053|
    |Dordogne            |Aquitaine |412082 |
    |Gironde             |Aquitaine |1846743|
    |Landes              |Aquitaine |2226084|
    |Lot-et-Garonne      |Aquitaine |2555781|
    |Pyrénées-Atlantiques|Aquitaine |3206137|
    |Allier              |Auvergne  |343046 |
    |Cantal              |Auvergne  |491426 |
    ...
    +--------------------+----------|-------+
    • Cette fois, la fonction analytique s'applique progressivement sur les lignes de la partition
    • La fenêtre ciblée correspond à ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW (détails diapo suivante)
  • Exemple avec deux fenêtrages :
    SELECT col_nom, col_region, col_superficie,
       AVG(col.col_superficie) OVER (PARTITION BY col_region) AS supMoyByReg,
       col_population,
       AVG(col_population) OVER (PARTITION BY col_region) AS popMoyByReg,
       (SELECT avg(col_population) FROM collectivite)
    FROM collectivite col
    WHERE col_region LIKE '%Normandie';
    +--------------+---------------+--------------+-----------+--------------+-----------+---------+
    |col_nom       |col_region     |col_superficie|supmoybyreg|col_population|popmoybyreg|avg      |
    +--------------+---------------+--------------+-----------+--------------+-----------+---------+
    |Calvados      |Basse-Normandie|5548          |5863       |680908        |490293.33  |626826.68|
    |Manche        |Basse-Normandie|5938          |5863       |497762        |490293.33  |626826.68|
    |Orne          |Basse-Normandie|6103          |5863       |292210        |490293.33  |626826.68|
    |Eure          |Haute-Normandie|6040          |6159       |582822        |877782.5   |626826.68|
    |Seine-maritime|Haute-Normandie|6278          |6159       |1172743       |877782.5   |626826.68|
    +--------------+---------------+--------------+-----------+--------------+-----------+---------+