Oracle窗口从句简析
对Oracle窗口一直搞不清楚,最近看了Laurent Schneider 写的"Advanced SQL Programming"一书对于这部分的描述,感觉写的很清楚,故摘译下来,以备查看。
www.2cto.com
窗口
partition从句并不是限制分析函数运算范围的唯一方法。当使用ROWS BETWEEN从句时,行就会被排序,一个窗口就会被定义。
Sql代码
SELECT
ENAME,
HIREDATE,
SAL,
MAX
(
SAL
)
OVER
(
ORDER BY
HIREDATE,
ENAME
ROWS BETWEEN
UNBOUNDED PRECEDING
AND
1 PRECEDING
) MAX_BEFORE,
MAX
(
SAL
)
OVER
(
ORDER BY
HIREDATE,
ENAME
ROWS BETWEEN
1 FOLLOWING
AND
UNBOUNDED FOLLOWING
) MAX_AFTER
FROM
EMP
ORDER BY
HIREDATE,
ENAME;
www.2cto.com
引用
ENAME HIREDATE SAL MAX_BEFORE MAX_AFTER
---------- --------- ---------- ---------- ----------
SMITH 17-DEC-80 800 5000
ALLEN 20-FEB-81 1600 800 5000
WARD 22-FEB-81 1250 1600 5000
JONES 02-APR-81 2975 1600 5000
BLAKE 01-MAY-81 2850 2975 5000
CLARK 09-JUN-81 2450 2975 5000
TURNER 08-SEP-81 1500 2975 5000
MARTIN 28-SEP-81 1250 2975 5000
KING 17-NOV-81 5000 2975 3000
FORD 03-DEC-81 3000 5000 3000
JAMES 03-DEC-81 950 5000 3000
MILLER 23-JAN-82 1300 5000 3000
SCOTT 19-APR-87 3000 5000 1100
ADAMS 23-MAY-87 1100 5000
对于每一行而言,当前行之前的最高薪水和之后的最高薪水会被返回。ORDER BY从句在这儿不是用于排名,而是用于声明一个窗口。
用ORDER BY从句进行合计可以产生累进的合计值。
Sql代码
SELECT
ENAME,
SAL,
SUM(SAL) OVER (ORDER BY ENAME ROWS UNBOUNDED PRECEDING) CUMSUM
FROM
EMP;
www.2cto.com
引用
ENAME SAL CUMSUM
---------- ---------- ----------
ADAMS 1100 1100
ALLEN 1600 2700
BLAKE 2850 5550
CLARK 2450 8000
FORD 3000 11000
JAMES 950 11950
JONES 2975 14925
KING 5000 19925
MARTIN 1250 21175
MILLER 1300 22475
SCOTT 3000 25475
SMITH 800 26275
TURNER 1500 27775
WARD 1250 29025
www.2cto.com
最低的边界就是UNBOUNDED PRECEDING(第一行),当前行是CURRENT ROW,最高的行是UNBOUNDED FOLLOWING(最后一行)。
当前行之前和之后的行使用n PRECEDING和n FOLLOWING来获得,n是指与当前行的相对位置。
当没有声明BETWEEN时,窗口默认于当前行结束。
Sql代码
SELECT
ENAME,
SAL,
AVG(SAL) OVER (ORDER BY SAL ROWS 1 PRECEDING) AVG
FROM
EMP;
引用
ENAME SAL AVG
---------- ---------- ----------
SMITH 800 800
JAMES 950 875
ADAMS 1100 1025
WARD 1250 1175
MARTIN 1250 1250
MILLER 1300 1275
TURNER 1500 1400
ALLEN 1600 1550
CLARK 2450 2025
BLAKE 2850 2650
JONES 2975 2912.5
SCOTT 3000 2987.5
FORD 3000 3000
KING 5000 4000
为当前行和上一行计算平均值。窗口开始于当前行之前的上一行,结束于当前行。
www.2cto.com
RANGE与ROWS类似,但间隔不是行数,而是数值或者时间。
Sql代码
SELECT
ENAME,
SAL,
SAL*.9 LOW,
SAL*1.1 HIGH,
COUNT