Toute différence entre « ligne active » et « 0 précédent / suivant » dans la clause de fenêtrage de fonctions analytiques Oracle?
Question
Certaines des fonctions analytiques d'Oracle permettent une fenêtrage clause pour spécifier un sous-ensemble de la partition en cours, en utilisant des mots clés tels que « sans bornes précédent / suivant », « ligne en cours », ou « value_expr précédent / suivant » où value_expr est un décalage physique ou logique de la ligne en cours ou la valeur (selon que vous avez spécifié ligne ou RANGE, respectivement).
Voici un exemple en utilisant scott / tigre qui affiche employés dans dept 30, et un décompte du nombre d'employés dans leur département embauchés avant eux (y compris eux-mêmes):
select deptno,
empno,
hiredate,
count(*) over (partition by deptno
order by hiredate
range between unbounded preceding and current row) cnt_hired_before1,
count(*) over (partition by deptno
order by hiredate
range between unbounded preceding and 0 preceding) cnt_hired_before2
from emp
where deptno = 30
order by deptno, hiredate;
... quelqu'un peut-il donner un exemple ou la documentation où « ligne courante » est différent de « 0 précédent / suivant »? Il semble tout comme le sucre syntaxique pour moi ...
La solution
Il ne compte pas vraiment que vous utilisez. Ce sont deux façons différentes d'exprimer le fenêtrage, mais l'optimiseur effectuera la requête de la même manière. Le terme « ligne actuelle » est celle qui est commune à plusieurs bases de données avec des fonctions analytiques, non seulement Oracle. Il est plus d'une différence de style, de la même manière que certaines personnes préfèrent count (*) sur le nombre (1).
Autres conseils
La documentation Oracle que je dois remettre (Oracle 9.2) dit:
Si vous avez spécifié RANGE:
- value_expr est une logique de décalage. Il doit être une constante ou une expression est évaluée à une valeur numérique positive ou un intervalle littéral.
Cela signifie que vous ne devriez pas vraiment utiliser 0 car il n'est pas une valeur numérique positive. Mais, il est évidemment possible d'utiliser 0 précédent / suivant, puisque vous êtes.
Il est tout ce que vous essayez d'accomplir. Vous pouvez utiliser RANGE ENTRE / ENTRE RANGS utiliser pour trouver LAST_VALUE dans les sous-ensemble ou comparer les choses dans un sous-ensemble. Mais certainement vous n'avez pas besoin pour l'exemple que vous avez fourni.
select deptno,
empno,
hiredate,
count(*) over (partition by deptno, trunc(hiredate,'mm')) cnt_same_month
from emp
where deptno = 30
order by deptno, hiredate