Fonctions de fenêtre avec des spécificateurs RANGE

Dans RAQL, SELECT aggregationFunction(x) OVER(ORDER BY y) FROM s est équivalent sur le plan sémantique à SELECT aggregationFunction (x) OVER(ORDER BY y ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM s. Toutefois, la norme SQL définit la sémantique afin qu'elle corresponde à SELECT aggregationFunction (x) OVER(ORDER BY y RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM s, ce qui signifie que la ligne actuelle, mais également toutes les lignes 'appariés' (lignes identiques à la ligne actuelle en ce qui concerne leur ordre) sont contenues dans la fenêtre. Autrement dit, un agrégat continu sans spécification explicite du cadre de fenêtre produit à l'heure actuelle des résultats différents dans RAQL et dans tout SGBD compatible avec la norme SQL.

Pour garantir un haut niveau de compatibilité avec la norme SQL, les cadres des fenêtres peuvent également définis avec le mot-clé RANGE.

Sémantique

Les cadres des fenêtres définis avec le mot-clé ROWS sont faciles à comprendre. La clause du cadre de fenêtre ROWS BETWEEN x PRECEDING AND y FOLLOWING définit simplement deux décalages x et y, qui déterminent pour chaque ligne dans la partition d'entrée le premier et le dernier numéros des lignes de la fenêtre correspondante par rapport au numéro de ligne actuel. PRECEDING et FOLLOWINGindiquent seulement si le décalage est négatif (le numéro de ligne précède le numéro de ligne actuel) ou positif.

Table 2. Exemple

rowNumber

ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING

ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING

ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING

1

Window = [1,4]

Window = []

Window = [1,10]

2

Window = [1,5]

Window = [1,1]

Window = [2,10]

3

Window = [1,6]

Window = [1,2]

Window = [3,10]

4

Window = [1,7] (du numéro de ligne 4-3 à 4+3)

Window = [1,3]

Window = [4,10]

5

Window = [2,8]

Window = [2,4]

Window = [5,10]

6

Window = [3,9]

Window = [3,5]

Window = [6,10]

7

Window = [4,10]

Window = [4,6]

Window = [7,10]

8

Window = [5,10]

Window = [5,7]

Window = [8,10]

9

Window = [6,10]

Window = [6,8]

Window = [9,10]

10

Window = [7,10]

Window = [7,9]

Window = [10,10]

D'un autre côté, la sémantique des spécifications des cadres de fenêtres utilisant le mot-clé RANGE ne dépend pas des numéros physiques des lignes, mais des valeurs réelles d'une colonne. Pourtant, la clause du cadre de fenêtre définit deux décalages x et y, mais ces décalages ne sont pas ajoutés au numéro de ligne, mais à une valeur de colonne réelle. De ce fait, toute spécification de cadre de fenêtre impliquant RANGE et un décalage différent de UNBOUNDED PRECEDING, UNBOUNDED FOLLOWING ou CURRENT ROW exige que la fenêtre soit disposée sur une seule colonne et que cette colonne contienne des données de type numérique (afin de permettre le calcul arithmétique du décalage).

Table 3. Exemple

rowNumber

salary

SELECT avg(salary) OVER (ORDER BY salary RANGE BETWEEN 300 PRECEDING AND 300 FOLLOWING) FROM ...

fenêtre considérée

1

1750

1850

[1450,2050]

salaires compris entre 1750 - 300 et 1750 + 300

2

1900

1850

[1600,2200]

3

1900

1850

[1600,2200]

4

2200

2100

[1900,2500]

5

2400

2300

[2100,2700]

6

2750

2866,67

[2450,3050]

7

2900

2980

[2600,3200]

8

2950

2980

[2650,3250]

9

3100

2980

[2800,3400]

10

3200

2980

[2900,3500]

Table 4. Exemple

rowNumber

salary

SELECT avg(salary) OVER (ORDER BY salary RANGE BETWEEN 300 PRECEDING AND 300 FOLLOWING) FROM ...

fenêtre considérée

1

1750

1

[1750,1750]

salaires compris entre 1750 - 0 et 1750 + 0

2

1900

2

[1900,1900]

3

1900

2

[1900,1900]

4

2200

1

[2200,2100]

5

2400

1

[2400,2400]

6

2750

1

[2750,2750]

7

2900

1

[2900,2900]

8

2950

1

[2950,2950]

9

3100

1

[3100,3100]

10

3200

1

[3200,3200]

Remarque : Les décalages dans une clause de cadre RANGE définissent des décalages logiques dans la séquence ordonnée définie par la clause order by. Si la clause order by précise un ordre décroissant (voir l'exemple suivant), le décalage 10 PRECEDING se traduit par "une valeur qui précède la valeur actuelle dans la séquence actuelle et qui diffère au plus de 10 (années/unités/...) »

Table 5. Exemple

rowNumber

age

SELECT COUNT(*) OVER (ORDER BY age DESC RANGE 10 PRECEDING) FROM ...

fenêtre considérée

1

75

1

[85, 75]

âges compris entre 75 + 10 et 75 - 0

2

68

2

[78, 68]

3

68

2

[72, 62]

4

56

2

[66, 56]

5

55

3

[65, 55]

6

51

3

[61, 51]

7

48

5

[58, 48]

8

48

5

[58, 48]

9

47

6

[57, 47]

10

43

5

[53, 43]

Requêtes impactées

Comme mentionné précédemment, le nouveau spécificateur RANGE a été introduit pour assurer la compatibilité avec la norme SQL. Il n'existe cependant que très peu de cas où des requêtes existantes risquent d'être impactées par ces changements. Seules les requêtes définissant une fonction de fenêtre avec

Si les expressions order by sont uniques, si chaque ligne n'a aucune ligne appariée en ce qui concerne l'ordre et si la clause du cadre de fenêtre ajouté implicitement RANGE UNBOUNDED PRECEDING est équivalente à ROWS UNBOUNDED PRECEDING, les résultats de la requête sont alors les mêmes qu'auparavant. Toutefois, si la spécification order by n'est pas unique, certaines lignes risquent d'avoir une ou plusieurs lignes appariées, si bien que les résultats de la requête sont différents du résultat fourni par les versions RAQL précédentes et l'utilisateur pourrait souhaiter ajouter explicitement une clause de cadre de fenêtre ROWS UNBOUNDED PRECEDING pour produire les résultats antérieurs.