Fonction de fenêtre (SQL) - Window function (SQL)

En SQL , une fonction de fenêtre ou une fonction analytique est une fonction qui utilise les valeurs d'une ou plusieurs lignes pour renvoyer une valeur pour chaque ligne. (Cela contraste avec une fonction d'agrégation , qui renvoie une valeur unique pour plusieurs lignes.) Les fonctions de fenêtre ont une clause OVER; toute fonction sans clause OVER n'est pas une fonction de fenêtre, mais plutôt une fonction d'agrégation ou à une seule ligne (scalaire).

A titre d'exemple, voici une requête qui utilise une fonction de fenêtre pour comparer chaque employé avec le salaire moyen de son service (exemple de la documentation PostgreSQL ):

SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;

Production:

 depname  | empno | salary |          avg          
----------+-------+--------+----------------------
develop   |    11 |   5200 | 5020.0000000000000000
develop   |     7 |   4200 | 5020.0000000000000000
develop   |     9 |   4500 | 5020.0000000000000000
develop   |     8 |   6000 | 5020.0000000000000000
develop   |    10 |   5200 | 5020.0000000000000000
personnel |     5 |   3500 | 3700.0000000000000000
personnel |     2 |   3900 | 3700.0000000000000000
sales     |     3 |   4800 | 4866.6666666666666667
sales     |     1 |   5000 | 4866.6666666666666667
sales     |     4 |   4800 | 4866.6666666666666667
(10 rows)

La PARTITION BY clause regroupe les lignes en partitions et la fonction est appliquée à chaque partition séparément. Si la PARTITION BY clause est omise (comme si nous avons une OVER() clause vide ), alors l'ensemble de résultats est traité comme une seule partition. Pour cette requête, le salaire moyen indiqué serait la moyenne prise sur toutes les lignes.

Les fonctions de fenêtre sont évaluées après agrégation (après la GROUP BY clause et les fonctions d'agrégation sans fenêtre, par exemple).

Syntaxe

Selon la documentation PostgreSQL, une fonction de fenêtre a la syntaxe de l'une des suivantes:

function_name ([expression [, expression ... ]]) OVER window_name
function_name ([expression [, expression ... ]]) OVER ( window_definition )
function_name ( * ) OVER window_name
function_name ( * ) OVER ( window_definition )

window_definition a la syntaxe:

[ existing_window_name ]
[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ frame_clause ]

frame_clause a la syntaxe de l'un des éléments suivants:

{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ]
{ RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ]

frame_start et frame_end peut être UNBOUNDED PRECEDING , offset PRECEDING , CURRENT ROW , offset FOLLOWING ou UNBOUNDED FOLLOWING . frame_exclusion peut être EXCLUDE CURRENT ROW , EXCLUDE GROUP , EXCLUDE TIES ou EXCLUDE NO OTHERS .

expression fait référence à toute expression qui ne contient pas d'appel à une fonction de fenêtre.

Notation:

  • Les crochets [] indiquent les clauses facultatives
  • Les accolades {} indiquent un ensemble d'options différentes possibles, chaque option étant délimitée par une barre verticale |

Exemple

Les fonctions de fenêtre permettent d'accéder aux données dans les enregistrements juste avant et après l'enregistrement en cours. Une fonction de fenêtre définit un cadre ou une fenêtre de lignes d'une longueur donnée autour de la ligne actuelle et effectue un calcul sur l'ensemble de données de la fenêtre.

      NAME |
------------
      Aaron| <-- Preceding (unbounded)
     Andrew|
     Amelia|
      James|
       Jill|
     Johnny| <-- 1st preceding row
    Michael| <-- Current row
       Nick| <-- 1st following row
    Ophelia|
       Zach| <-- Following (unbounded)

Dans le tableau ci-dessus, la requête suivante extrait pour chaque ligne les valeurs d'une fenêtre avec une ligne précédente et une suivante:

 SELECT
  LAG(name, 1) 
    OVER(ORDER BY name) "prev",
  name, 
  LEAD(name, 1) 
    OVER(ORDER BY name) "next"
 FROM people
 ORDER BY name

La requête de résultat contient les valeurs suivantes:

|     PREV |     NAME |     NEXT |
|----------|----------|----------|
|    (null)|     Aaron|    Andrew|
|     Aaron|    Andrew|    Amelia|
|    Andrew|    Amelia|     James|
|    Amelia|     James|      Jill|
|     James|      Jill|    Johnny|
|      Jill|    Johnny|   Michael|
|    Johnny|   Michael|      Nick|
|   Michael|      Nick|   Ophelia|
|      Nick|   Ophelia|      Zach|
|   Ophelia|      Zach|    (null)|

Histoire

Les fonctions de fenêtre ont été introduites dans SQL: 2003 et ont été étendues dans les spécifications ultérieures.

Voir également

Les références