Oracle分析函数

Oracle分析函数

1.分析函数定义

分析函数通过将行分组后,再计算这些分组的统计值,并且每一组的每一行都可以返回一个统计值。分析函数通过分析子句将行分组,一个分组称为一个窗口,每一行都对应有一个在行上滑动的窗口,该窗口确定当前行的计算范围。窗口的大小可以是物理的(行号)也可以是逻辑的(取值范围),比如时间。

分析函数通常用于计算数据累计值、数据移动值、数据中间值或输出集合报表等。

另外,除了最后的order by子句,分析函数是一个查询中最后被执行的操作,所有的join,where,group
by,having语句都在分析函数之前执行,因此分析函数只能出现在select语句或者order by子句中

2.语法规则

1. 分析函数语法

analytic_function([arguments]) OVER( [partition_by(column)]
[order_by(column)[windowing_clause]] )

2.注释
analytic_function:函数名;
arguments:该分析函数要统计的参数;
over():开窗函数;
partition_by():按哪个字段划分组,如果省略了分区子句,则全部的结果集被看作是一个单一的组;
order_by():用以指定分组中数据的排序方式,可加nulls first | nulls last,指定若返回行包含空值,该值应该出现在排序序列的前面还是后面(升序默认后面,降序默认前面);
windowing_clause:开窗子句,定义分析函数在操作行上的集合,有三种开窗方式:rows、 range、Specifying滑动窗口(未知),如下

windowing_clause :=
{rows | range}
{between
{unbounded preceding | current row | value_expr {preceding | following}}
and
{unbounded following| current row | value_expr {preceding}}

rows | range 这两个关键字为每一行定义一个窗口,该窗口用于计算函数结果(物理或逻辑的行的集合),然后对窗口(这里指一个不断变动的数据范围)中的每一行应用分析函数。
rows:指定窗口以物理单位(行)构成;
range:指定窗口以逻辑偏移量构成;
between…and 子句:用来指定窗口的起点和终点。若不使用between而仅指定一个终点,则默认第一行为起点,终点为当前行;
unbounded preceding:指明窗口开始于分组的第一行;只能用于指定起点;
unbounded following:指明窗口结束于分组的最后一行,只能用于指定终点;
current row :1.用作起点时,指明窗口开始于当前行或当前值,这种情况下终点不能为value_expr preceding。2.用作终点时,指明窗口结束于当前行或当前值,这种情况下终点不能为value_expr following;
value_expr:物理偏移量,即指定为rows时,它必须是常量或者值为正数值的表达式,可以设置为1,2,3;若指定为range,则为逻辑偏移量,它必须为常量,或者值为正数值的表达式,或时间间隔文字常量;
1 preceding --译为当前行的前一行,以此类推;
1 following --译为当前行的下一行,以此类推;
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW --译为第一行至当前行的汇总;
BETWEEN 1 preceding AND current row --指当前行的上一行(rownum-1)到当前行的汇总;

  • 整体释义:函数以某个字段patition by 分组,同时在over()开窗函数中制定每个分组的order by排序方式后,从起点至终点进行扫描计算,返回该函数的统计值。

3.简单分析函数示例

1. 显示各部门员工的工资,并附带显示该部分的最高工资

SELECT E.DEPTNO,
       E.EMPNO,
       E.ENAME,
       E.SAL,
       LAST_VALUE(E.SAL) 
       OVER(PARTITION BY E.DEPTNO 
            ORDER BY E.SAL ROWS 
            --unbounded preceding and unbouned following针对当前所有记录的前一条、后一条记录,也就是表中的所有记录
            --unbounded:不受控制的,无限的
            --preceding:在...之前
            --following:在...之后
            BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_SAL
  FROM EMP E;

2. 按照deptno分组,然后计算每组值的总和

SELECT EMPNO,
       ENAME,
       DEPTNO,
       SAL,
       --第一种方法:
       SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY ENAME) max_sal
  FROM SCOTT.EMP;

--第二种方法:ROWS BETWEEN unbounded preceding AND current row  是指第一行至当前行的汇总,总和取分组的最后一行

--第三种方法
ROWS BETWEEN current row AND unbounded following 指当前行到最后一行的汇总,总和取分组的第一行

4.注意事项

  1. 分析函数不能直接嵌套,但可以在一个子查询中应用分析函数,并通过它计算另外的分析函数;
  2. range限制仅对NUMBERS和DATES起作用,不能处理VARCHAR2类型,且range需与order by固定搭配,并且order by中只能有一列;利用ROW分区,就没有RANGE分区那样的限制了,数据可以是任何类型,且ORDER BY 可以包括很多列;
  3. 若完全忽略windowing_caluse,则默认为range between unbounded preceding and current row;
  4. 与聚合函数区别:普通的聚合函数用group by分组,每个分组返回一个统计值,而分析函数采用partition by分组,并且每组每行都可以返回一个统计值;

5.两个order by的执行时机

(这点网上有很多都已经解释了,这里记录下以备回顾复习)

分析函数(以及与其配合的开窗函数over())是在整个sql查询结束后(sql语句中的order by的执行比较特殊)再进行的操作, 也就是说sql语句中的order by也会影响分析函数的执行结果:

a) 两者一致:如果sql语句中的order by满足与分析函数配合的开窗函数over()分析时要求的排序,即sql语句中的order by子句里的内容和开窗函数over()中的order by子句里的内容一样,
那么sql语句中的排序将先执行,分析函数在分析时就不必再排序;

b) 两者不一致:如果sql语句中的order by不满足与分析函数配合的开窗函数over()分析时要求的排序,即sql语句中的order by子句里的内容和开窗函数over()中的order by子句里的内容不一样,

那么sql语句中的排序将最后在分析函数分析结束后执行排序。

总结:一致按sql排;若sql有而分析无,则按sql先排序后分析;若SQL和分析都有排序,则按分析先排序且分析,最后才sql排序

6.常见分析函数

事前准备

--创建测试数据——部门表
CREATE TABLE T_ZDW_DEPT190810 AS
WITH DEPT AS
(SELECT 10 AS DEPTNO,'ACCOUNTING' AS DNAME,'ZHONGSHAN' AS LOC FROM DUAL UNION ALL
SELECT 20 AS DEPTNO,'RESEARCH' AS DNAME,'GUANGZHOU' AS LOC FROM DUAL UNION ALL
SELECT 30 AS DEPTNO,'SALES' AS DNAME,'SHENZHENG' AS LOC FROM DUAL UNION ALL
SELECT 40 AS DEPTNO,'OPERATIONS' AS DNAME,'DONGGUAN' AS LOC FROM DUAL)
SELECT * FROM DEPT;

--创建测试数据——工资表
CREATE TABLE T_ZDW_EMP190810 AS 
WITH EMP AS
(SELECT 7369 AS EMPNO,'SMITH' AS ENAME,'CLERK' AS JOB,'7902'AS MGR,to_date('17-12-1980','dd-mm-yyyy') AS HIREDATE,800 AS SAL,NULL AS COMM,20 AS DEPTNO FROM DUAL UNION ALL
SELECT 7499 AS EMPNO,'ALLEN' AS ENAME,'SALESMAN' AS JOB,'7698'AS MGR,to_date('20-2-1981','dd-mm-yyyy') AS HIREDATE,1600 AS SAL,300 AS COMM,30 AS DEPTNO FROM DUAL UNION ALL
SELECT 7521 AS EMPNO,'WARD' AS ENAME,'SALESMAN' AS JOB,'7698'AS MGR,to_date('22-2-1981','dd-mm-yyyy') AS HIREDATE,1250 AS SAL,500 AS COMM,30 AS DEPTNO FROM DUAL UNION ALL
SELECT 7566 AS EMPNO,'JONES' AS ENAME,'MANAGER' AS JOB,'7839'AS MGR,to_date('2-4-1981','dd-mm-yyyy') AS HIREDATE,2975 AS SAL,NULL AS COMM,20 AS DEPTNO FROM DUAL UNION ALL
SELECT 7654 AS EMPNO,'MARTIN' AS ENAME,'SALESMAN' AS JOB,'7698'AS MGR,to_date('28-9-1981','dd-mm-yyyy') AS HIREDATE,1250 AS SAL,1400 AS COMM,30 AS DEPTNO FROM DUAL UNION ALL
SELECT 7698 AS EMPNO,'BLAKE' AS ENAME,'MANAGER' AS JOB,'7839'AS MGR,to_date('1-5-1981','dd-mm-yyyy') AS HIREDATE,2850 AS SAL,NULL AS COMM,30 AS DEPTNO FROM DUAL UNION ALL
SELECT 7782 AS EMPNO,'CLARK' AS ENAME,'MANAGER' AS JOB,'7839'AS MGR,to_date('9-6-1981','dd-mm-yyyy') AS HIREDATE,2450 AS SAL,NULL AS COMM,10 AS DEPTNO FROM DUAL UNION ALL
SELECT 7788 AS EMPNO,'SCOTT' AS ENAME,'ANALYST' AS JOB,'7566'AS MGR,to_date('13-4-1987','dd-mm-yyyy') AS HIREDATE,3000 AS SAL,NULL AS COMM,20 AS DEPTNO FROM DUAL UNION ALL
SELECT 7839 AS EMPNO,'KING' AS ENAME,'PRESIDENT' AS JOB,NULL AS MGR,to_date('17-11-1981','dd-mm-yyyy') AS HIREDATE,5000 AS SAL,NULL AS COMM,10 AS DEPTNO FROM DUAL UNION ALL
SELECT 7844 AS EMPNO,'TURNER' AS ENAME,'SALESMAN' AS JOB,'7698'AS MGR,to_date('8-9-1981','dd-mm-yyyy') AS HIREDATE,1500 AS SAL,NULL AS COMM,30 AS DEPTNO FROM DUAL UNION ALL
SELECT 7876 AS EMPNO,'ADAMS' AS ENAME,'CLERK' AS JOB,'7788'AS MGR,to_date('13-5-1987','dd-mm-yyyy') AS HIREDATE,1100 AS SAL,NULL AS COMM,20 AS DEPTNO FROM DUAL UNION ALL
SELECT 7900 AS EMPNO,'JAMES' AS ENAME,'CLERK' AS JOB,'7698'AS MGR,to_date('3-12-1981','dd-mm-yyyy') AS HIREDATE,950 AS SAL,NULL AS COMM,30 AS DEPTNO FROM DUAL UNION ALL
SELECT 7902 AS EMPNO,'FORD' AS ENAME,'ANALYST' AS JOB,'7566'AS MGR,to_date('3-12-1981','dd-mm-yyyy') AS HIREDATE,3000 AS SAL,NULL AS COMM,20 AS DEPTNO FROM DUAL UNION ALL
SELECT 7934 AS EMPNO,'MILLER' AS ENAME,'CLERK' AS JOB,'7782'AS MGR,to_date('23-1-1982','dd-mm-yyyy') AS HIREDATE,1300 AS SAL,NULL AS COMM,10 AS DEPTNO FROM DUAL 
)
SELECT * FROM EMP;
1.Lag()函数和 lead() 函数

语法规则:

–Lag函数按偏移量取当前行之前第几行的值,如当前行号为rn,则取行号为rn-offset。
lag(exp_str,offset,default) over() ;–partition by 可选,order by 必选。

Lead函数按偏移量取当前行之后第几行的值,如当前行号为rn,则取行号为rn+offset。
lead(exp_str,offset,default) over();–partition by 可选,order by 必选。

  • 注释:
  • exp_str 指的是要做对比的字段;
  • offset 是exp_str字段的偏移量,即offset 为N ,指的是在表中从当前行位置向前数N行就是我们所要找的那一行了(当前行是4,offset为3时,要找的行即4-3 =1);
    offset的默认值为1!
  • default 当offset的值已经超出了表的范围时,lag()函数将default这个参数值作为函数的返回值;default 参数的默认值为空值null;

应用示例

--默认偏移量为1default为空,第一行last_sal显示空值,第二行开始last_sal显示为上一行的sal值;
select ename, job, sal, lag(sal) over(order by sal) last_sal from T_ZDW_EMP190810;
--结果显示:
1	SMITH	CLERK		800	    --这里为空
2	JAMES	CLERK		950	    800
3	ADAMS	CLERK		1100	950
4	WARD	SALESMAN	1250	1100
5	MARTIN	SALESMAN	1250	1250
6	MILLER	CLERK		1300	1250
7	TURNER	SALESMAN	1500	1300
8	ALLEN	SALESMAN	1600	1500
9	CLARK	MANAGER		2450	1600
10	BLAKE	MANAGER		2850	2450
11	JONES	MANAGER		2975	2850
12	SCOTT	ANALYST		3000	2975
13	FORD	ANALYST		3000	3000
14	KING	PRESIDENT	5000	3000

--default默认值为500
select ename,job,sal ,lag(sal,1,500) over(order by sal) last_sal from T_ZDW_EMP190810;

--这里加多了partition by的分组,即以job的同一值分组计算lag()的返回值
select ename,job,sal ,lag(sal,1) over(partition by job order by sal) last_sal from T_ZDW_EMP190810;
--结果显示:
1	FORD	ANALYST 	3000	--
2	SCOTT	ANALYST		3000	3000
3	SMITH	CLERK		800	    --
4	JAMES	CLERK		950		800
5	ADAMS	CLERK		1100	950
6	MILLER	CLERK		1300	1100
7	CLARK	MANAGER		2450	--
8	BLAKE	MANAGER		2850	2450
9	JONES	MANAGER		2975	2850
10	KING	PRESIDENT	5000	--
11	MARTIN	SALESMAN	1250	--
12	WARD	SALESMAN	1250	1250
13	TURNER	SALESMAN	1500	1250
14	ALLEN	SALESMAN	1600	1500

--默认偏移量为1default为空,last_sal最后一行会显示为空;
select ename,job,sal ,lead(sal) over(order by sal) last_sal from T_ZDW_EMP190810;
结果显示:
1	SMITH	CLERK		800		950
2	JAMES	CLERK		950		1100
3	ADAMS	CLERK		1100	1250
4	WARD	SALESMAN	1250	1250
5	MARTIN	SALESMAN	1250	1300
6	MILLER	CLERK		1300	1500
7	TURNER	SALESMAN	1500	1600
8	ALLEN	SALESMAN	1600	2450
9	CLARK	MANAGER		2450	2850
10	BLAKE	MANAGER		2850	2975
11	JONES	MANAGER		2975	3000
12	SCOTT	ANALYST		3000	3000
13	FORD	ANALYST		3000	5000
14	KING	PRESIDENT	5000	--这里显示为空

--分组后,每组的最后一行LAST_SAL为空
select ename,job,sal ,lead(sal,1) over(partition by job order by sal) last_sal from T_ZDW_EMP190810;
结果显示:
1	FORD	ANALYST		3000	3000
2	SCOTT	ANALYST		3000	--
3	SMITH	CLERK		800		950
4	JAMES	CLERK		950		1100
5	ADAMS	CLERK		1100	1300
6	MILLER	CLERK		1300	--
7	CLARK	MANAGER		2450	2850
8	BLAKE	MANAGER		2850	2975
9	JONES	MANAGER		2975	--
10	KING	PRESIDENT	5000	--
11	MARTIN	SALESMAN	1250	1250
12	WARD	SALESMAN	1250	1500
13	TURNER	SALESMAN	1500	1600
14	ALLEN	SALESMAN	1600	--

注意点
使用这两个分析函数的时候注意空值 或者null 给数据带来的影响,数据是否允许为空或者null计算的时候会导致一定的差错,如:800-null = null;

2.Rank()函数

语法规则:

–Rank()函数:跳跃排序,并给出序号(非连续排名)。
rank() over ([partition by 分组字段] order by 排序字段 顺序) ;–partition by 可选,order by 必选。

  • 注释:
    无(参照字面意思)

应用示例

--查询emp表中每个部门中工资前3名的员工信息,如果遇到工资一样的,则排名一样(如部门20所示),
--下一级工资排名为跳序,如:1,2,2,2,5...
SELECT *
  FROM (SELECT e.*, rank() over(partition BY deptno order by sal desc) rk
          FROM T_ZDW_EMP190810 e) t1
 WHERE t1.rk <= 3 ;
 --结果显示:
1	7839	KING	PRESIDENT			1981/11/17	5000	--	10	1
2	7782	CLARK	MANAGER		7839	1981/6/9	2450	--	10	2
3	7934	MILLER	CLERK		7782	1982/1/23	1300	--	10	3
4	7788	SCOTT	ANALYST		7566	1987/4/13	3000	--	20	1
5	7902	FORD	ANALYST		7566	1981/12/3	3000	--	20	1
6	7566	JONES	MANAGER		7839	1981/4/2	2975	--	20	3
7	7698	BLAKE	MANAGER		7839	1981/5/1	2850	--	30	1
8	7499	ALLEN	SALESMAN	7698	1981/2/20	1600	300	30	2
9	7844	TURNER	SALESMAN	7698	1981/9/8	1500	--	30	3


注意点
遇到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名,如上面查询结果部门20所示,1,1,3;

3.Dense_rank()函数

语法规则:

–Dense_rank()函数:连续排序,并给出序号(连续排名)。
dense_rank() over ([partition by 分组字段] order by 排序字段 顺序) ;–partition by 可选,order by 必选。

  • 注释:
    无(参照字面意思)

应用示例

--查询emp表中每个部门中工资前3名的员工信息,如果遇到工资一样的,则排名一样,
--下一级工资排名为顺序,如:1,2,2,2,3...
SELECT *
  FROM (SELECT e.*,
               dense_rank() over(partition BY deptno order by sal desc) rk
          FROM T_ZDW_EMP190810 e) t1
 WHERE t1.rk <= 3;
 --结果显示:
1	7839	KING	PRESIDENT	--		1981/11/17	5000	--	10	1
2	7782	CLARK	MANAGER		7839	1981/6/9	2450	--	10	2
3	7934	MILLER	CLERK		7782	1982/1/23	1300	--	10	3
4	7788	SCOTT	ANALYST		7566	1987/4/13	3000	--	20	1
5	7902	FORD	ANALYST		7566	1981/12/3	3000	--	20	1
6	7566	JONES	MANAGER		7839	1981/4/2	2975	--	20	2
7	7876	ADAMS	CLERK		7788	1987/5/13	1100	--	20	3
8	7698	BLAKE	MANAGER		7839	1981/5/1	2850	--	30	1
9	7499	ALLEN	SALESMAN	7698	1981/2/20	1600	300	30	2
10	7844	TURNER	SALESMAN	7698	1981/9/8	1500	--	30	3


注意点
当碰到相同数据时,此时所有相同数据的排名都是一样的,且下一个排名按顺序,如上面查询结果部门20所示,1,1,2;

4.Ntile()函数

语法规则:

–Ntile()函数:对一个数据分区中的有序结果集进行划分,将其分组为N份,并为每个小组分配一个唯一的组编号。这个函数在统计分析中是很有用的。例如,如果想移除异常值,你可以将它们分组到顶部或底部中,然后在统计分析的时候将这些值排除。

ntile([比例值]) over (order by 排序字段 顺序) ;–partition by 可选,order by 必选。

  • 注释:
    比例值:表示将分组内记录平均分成n份,多出的按照顺序依次分给前面的组

应用示例

--分组后,对sal分为2等份,
SELECT ENAME,
       SAL,
       DEPTNO,
       NTILE(2) OVER(PARTITION BY deptno ORDER BY SAL ASC NULLS LAST)
  FROM T_ZDW_EMP190810;
 --结果显示:
1	MILLER	1300	10	1
2	CLARK	2450	10	1
3	KING	5000	10	2
4	SMITH	800		20	1
5	ADAMS	1100	20	1
6	JONES	2975	20	1
7	SCOTT	3000	20	2
8	FORD	3000	20	2
9	JAMES	950		30	1
10	MARTIN	1250	30	1
11	WARD	1250	30	1
12	TURNER	1500	30	2
13	ALLEN	1600	30	2
14	BLAKE	2850	30	2

--分组后,对sal分为3等份,
SELECT ENAME,
       SAL,
       DEPTNO,
       NTILE(3) OVER(PARTITION BY deptno ORDER BY SAL ASC NULLS LAST)
  FROM T_ZDW_EMP190810;
 --结果显示:
1	MILLER	1300	10	1
2	CLARK	2450	10	2
3	KING	5000	10	3
4	SMITH	800		20	1
5	ADAMS	1100	20	1
6	JONES	2975	20	2
7	SCOTT	3000	20	2
8	FORD	3000	20	3
9	JAMES	950		30	1
10	MARTIN	1250	30	1
11	WARD	1250	30	2
12	TURNER	1500	30	2
13	ALLEN	1600	30	3
14	BLAKE	2850	30	3

注意点
当碰到相同数据时,此时所有相同数据的排名都是一样的,且下一个排名按顺序,如上面查询结果部门20所示,1,1,2;

5.First_value()和Last_value()函数

语法规则:

–First_value()函数:取首记录值。

first_value(字段值) over([partition by col1 ] order by col2) ;–partition by 可选,order by 可选。

–Last_value()函数:取尾记录值。

last_value(字段值) over([partition by col1 ] order by col2) ;–partition by 可选,order by 可选。

  • 注释:
    Last_value函数会默认统计范围是 rows between unbounded preceding and current row,若要获取到全表的最后一个值,需改写成:rows between unbounded preceding and unbounded following

应用示例

--结果first_value()比较直观,会显示按分组排序后排第一的时间值,last_value()需注意窗口范围
select empno,
       hiredate,
       deptno,
       first_value(hiredate) over(partition by deptno) first_value,
       last_value(hiredate) over(partition by deptno order by sal desc) last_value1,
       last_value(hiredate) over(partition by deptno order by sal desc rows between unbounded preceding and unbounded following) last_value2
  from T_ZDW_EMP190810;
 --结果显示:
   	EMPNO	HIREDATE DEPTNO FIRST_VAL   LAST_VAL1   LAST_VAL2
1	7934	1982/1/23	10	1982/1/23	1982/1/23	1982/1/23
2	7782	1981/6/9	10	1982/1/23	1981/6/9	1982/1/23
3	7839	1981/11/17	10	1982/1/23	1981/11/17	1982/1/23
4	7369	1980/12/17	20	1980/12/17	1980/12/17	1980/12/17
5	7876	1987/5/13	20	1980/12/17	1987/5/13	1980/12/17
6	7566	1981/4/2	20	1980/12/17	1981/4/2	1980/12/17
7	7902	1981/12/3	20	1980/12/17	1987/4/13	1980/12/17
8	7788	1987/4/13	20	1980/12/17	1987/4/13	1980/12/17
9	7900	1981/12/3	30	1981/12/3	1981/12/3	1981/12/3
10	7521	1981/2/22	30	1981/12/3	1981/9/28	1981/12/3
11	7654	1981/9/28	30	1981/12/3	1981/9/28	1981/12/3
12	7844	1981/9/8	30	1981/12/3	1981/9/8	1981/12/3
13	7499	1981/2/20	30	1981/12/3	1981/2/20	1981/12/3
14	7698	1981/5/1	30	1981/12/3	1981/5/1	1981/12/3

注意点
Last_value函数会默认统计范围是 rows between unbounded preceding and current row‘;
row_number函数返回一个唯一的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增,也可以使用row_number函数删除重复值,类似rownum(这点待补充测试脚本);

5.最值总和与平均值函数
  • Max()、Min()、Sum()、Avg()、Count()与Over()分析函数的一般语法配合使用。

语法规则:

  • 注释:

应用示例

WITH V AS(
SELECT 1 ITEM_NO,'000' OWNER_ID,81 AMOUNT_OF_PAGED FROM DUAL UNION ALL
SELECT 2,'000',5 FROM DUAL UNION ALL
SELECT 3,'000',5 FROM DUAL UNION ALL
SELECT 4,'000',8 FROM DUAL UNION ALL
SELECT 5,'000',11 FROM DUAL UNION ALL
SELECT 6,'000',18 FROM DUAL UNION ALL
SELECT 7,'000',1 FROM DUAL UNION ALL
SELECT 8,'000',24 FROM DUAL UNION ALL
SELECT 9,'000',11 FROM DUAL UNION ALL
SELECT 10,'000',14 FROM DUAL
)
SELECT V.ITEM_NO,V.OWNER_ID,V.AMOUNT_OF_PAGED,
           NVL(SUM(AMOUNT_OF_PAGED) 
                  OVER(PARTITION BY OWNER_ID ORDER BY ITEM_NO 
                  ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),0)+1 PAGE_NO
--要不想第一行改变值,可以将终点设置为1 PRECEDING,即前一行,当扫描第一行时,
--也就是从第一行起点到它的前一行,前一行为空,第一行就不会改变值
FROM V;

注意点

修改记录

时间内容
2019年10月23日第一次发布,未完成“5.最值总和与平均值函数”部分
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值