SAP HANA PROCEDURE(sap hana数据库 存储过程)

存储过程

内容引自HANA SQLScript第三部分储存过程-创建储存过程是真长

3.1CREATE PROCEDURE

1
2
3
4
5
6
7
8
CREATE PROCEDURE [<schema_name>.]<proc_name> [(<parameter_clause>)] [LANGUAGE <lang>] [SQL SECURITY <mode>]
[DEFAULT SCHEMA <default_schema_name>][READS SQL DATA [WITH RESULT VIEW ]] AS

BEGIN [SEQUENTIAL EXECUTION]

<procedure_body>

END

The CREATE PROCEDURE statement creates a procedure using the specified programming language .

DeepL翻译:CREATE PROCEDURE语句使用指定的编程语言创建一个过程。

3.1.1

  1. ::= [{,}…]
    1. ::= []
      1. ::= IN|OUT|INOUT
      2. ::= | |
        1. ::= DATE | TIME| TIMESTAMP | SECONDDATE | TINYINT | SMALLINT |INTEGER | BIGINT | DECIMAL | SMALLDECIMAL | REAL | DOUBLE
          | VARCHAR | NVARCHAR | ALPHANUM | VARBINARY | CLOB | NCLOB | BLOB
        2. ::= TABLE ()
          1. ::= [{, }…]
            1. ::=

输入或输出参数类型可以是标准的基础数据类型与表类型,但INOUT参数只能是标准数据类型

:默认为IN

:参数类型如果是表类型,这个表类型可以是预先使用Create Type…As Table语句创建的类型对象,也可以在指定存储过程参数类型时才定义表类型

3.1.2 LANGUAGE

::= SQLSCRIPT | R

默认为: SQLSCRIPT。指定存储过程实现的程序语言

3.1.3 SQL SECURITY

::= DEFINER | INVOKER

默认: DEFINER,指定存储过程的安全模式

DEFINER:Specifies that the execution of the procedure is performed with the privileges of the definer of the procedure.

DEFINER:只有存储过程的定义者才能执行?

INVOKER:Specifies that the execution of the procedure is performed with the privileges of the invoker of the procedure.

3.1.4 READS SQL DATA

存储过程为只读的,不能包含DDL与DML(INSERT、UPDATE、DELETE)语句(即只能使用查询SQL与DCL语句),如果调用其他存储过程,则被调用过程也是只读的。设置参数会有特定的优化

3.1.5 WITH RESULT VIEW

Specifies the result view to be used as the output of a read-only procedure.将只读取存储过程的输出看做结果视图

When a result view is defined for a procedure, it can be called by an SQL statement in the same way as a tableor view. See Example 2 - Using a result view below.定义了结果视图的存储过程,可以被其他查询SQL用来查询,此时存储过程就像一个表或视图

3.1.6 SEQUENTIAL EXECUTION

This statement will force sequential execution of the procedure logic. No parallelism takes place.不允许存储过程并行执行

3.1.7

::= [] 定义块
[] 异常处理块
存储体语句块

Defines the main body of the procedure according to the programming language selected.过程的主体由设定的程序语言来定义

3.1.7.1 定义变量

  1. ::= [{}…]
    1. ::= DECLARE {|||} ;
      1. <proc_variable>::= <variable_name_list> [**CONSTANT**] {<sql_type>|<array_datatype>}[NOT NULL][<proc_default>]
        1. ::= [{, <variable_name}…]
        2. ::= ARRAY [ = ]
          1. ::= ARRAY ( [ { , }…] )
        3. ::= (DEFAULT | ‘=’ ) |
      2. ::= {|}
        1. ::= [{, <variable_name}…]
        2. ::= TABLE()
          1. ::= ([{,}…])
      3. ::= CURSOR [ ( proc_cursor_param_list ) ] FOR ;
        1. ::= [{,}…]
          1. ::=
      4. ::= CONDITION | CONDITION FOR

CREATE procedure proc() LANGUAGE SQLSCRIPT AS

BEGIN

declare a int****default 2;–基本类型变量使用前一定要定义

​ – 如果某个变量是表类型的变量,可以不用声明,直接就可以使用,这与基本类型变量是不一样的

​ – ——基本类型变量使用前需要定义

​ –declare tab_var1 table(a int,b int); 表类型变量可不定义就使用

​ a := 1;

​ – a = 1; 基本类型变量赋值时,等号前一定要加冒号,这与表类型变量恰好相反

​ tab_var1 = select 1 as a,2 as b from dummy;

​ –tab_var1 := select 1 as a,2 as b from dummy; 这是错误,表类型变量赋值时,只能使用等号,不能在等号前加冒号,这与基本类型变量赋值相反

END;

暂时看到这了:太长了下次再接着看

3.1.7.2 异常处理

::= [{, }…]

::= DECLARE EXIT HANDLER FOR ;

::= {,}…]

::= SQLEXCEPTION | SQLWARNING | |

3.1.7.3 过程体

::= {}…

::= | | | | | | | |
| | | | | | | | | | |

3.1.7.3.1 内嵌块

::= BEGIN [][] END ;

::= [SEQUENTIAL EXECUTION] [AUTONOMOUS TRANSACTION]| [AUTONOMOUS TRANSACTION] [SEQUENTIAL
EXECUTION]

内嵌块, BEGIN 、 END是可以内嵌的

3.1.7.3.2 给变量赋值

::= = { | } ;| ‘[‘ ‘]’ = ;

= ARRAY_AGG ( . [ ORDER BY ] ) | CARDINALITY ( ) | TRIM_ARRAY
( , ) | ARRAY ( )

::=< array_variable_name > [{, < array_variable_name >}…] 这个是自己 加的,是否正确?

Assign values to variables. An can be either a simple expression, such as a character, a date, or a number, or it can be a scalar function or a scalar user-defined function.将值赋给变量。可以是一个简单的表达式(如字符、日期、数字表达式),或者是标准函数,或用户自定义函数

有关 ARRAY 、ARRAY_AGG、CARDINALITY、TRIM_ARRAY函数请参考后面数组函数

3.1.7.3.3 单个赋值

::= = | = | = | =

::= TRACE ( ) ;| CE_LEFT_OUTER_JOIN ( , ,’[‘ ‘]’ ] ) ;
| CE_RIGHT_OUTER_JOIN ( , ,’[‘ ‘]’ [ ] ) ; | CE_FULL_OUTER_JOIN ( , ,’[‘ ‘]’ [ ] ); | CE_JOIN ( , , ‘[‘ ‘]’ [] ) ;| CE_UNION_ALL ( , ) ;| CE_COLUMN_TABLE ( [ ] ) ; | CE_JOIN_VIEW ( [ ] ) ;| CE_CALC_VIEW ( [ ] ) ; | CE_OLAP_VIEW ( [ ] ) ; | CE_PROJECTION ( , ‘[‘ ‘]’ ) ; | CE_PROJECTION ( ) ; | CE_AGGREGATION ( , ‘[‘ ‘]’ [ ] ); | CE_CONVERSION ( , ‘[‘ ‘]’ [ ] ) ;| CE_VERTICAL_UNION ( , ‘[‘ ‘]’ ) ;| CE_COMM2R ( , , , , , ) ;

::= [.]

::= APPLY_FILTER ( { | }, ) ;

::= UNNEST ( ) [ WITH ORDINALITY ][] ;

::= [{, }…]

::= AS [table_name] ( )

::= [{, }…]

WITH ORDINALTIY:Appends an ordinal column to the return values.

3.1.7.3.4 多个赋值

::= () =

Assign values to a list of variables with only one function evaluation. For example, must be a scalar user defined function and the number of elements in must be equal to the number of output parameters of the scalar UDF(用户定义函数).

:用户自定义函数

函数的输入参数个数需与中的参数个数相同

3.1.7.3.5

::= IF THEN [SEQUENTIAL EXECUTION][] [] [] [] END IF ;

::= ELSEIF THEN [SEQUENTIAL EXECUTION][] []

::= ELSE [SEQUENTIAL EXECUTION][][]

You use IF - THEN - ELSE IF to control execution flow with conditionals.

3.1.7.3.6

::= LOOP [SEQUENTIAL EXECUTION][] [] END LOOP ;

You use loop to repeatedly execute a set of statements.

3.1.7.3.7

::= WHILE DO [SEQUENTIAL EXECUTION][] [] END WHILE ;

You use while to repeatedly call a set of trigger statements while a condition is true.

3.1.7.3.8

::= FOR IN [ REVERSE ] […] DO [SEQUENTIAL EXECUTION]

[]

[]

END FOR ;

You use FOR - IN loops to iterate over a set of data.

3.1.7.3.9

::= FOR AS [] DO [SEQUENTIAL EXECUTION]

[]

[]

END FOR ;

::= ( [ { , }…] )

You use FOR - EACH loops to iterate over all elements in a set of data.

3.1.7.3.10

::= BREAK ;

Terminates a loop.结束循环

3.1.7.3.11

::= CONTINUE ;

Skips a current loop iteration and continues with the next value.结束当前循环继续下一次循环

3.1.7.3.12

::= SIGNAL [] ;

You use the SIGNAL statement to explicitly raise an exception from within your trigger procedures.

3.1.7.3.13

::= RESIGNAL [] [] ;

You use the RESIGNAL statement to raise an exception on the action statement in an exception handler. If an error code is not specified, RESIGNAL will throw the caught exception.重新抛出异常?

::= |

::=

::=

You can SIGNAL or RESIGNAL a signal name or an SQL error code.

::= SET MESSAGE_TEXT = ‘

::=

You use SET MESSAGE_TEXT to deliver an error message to users when specified error is thrown during procedure execution.

3.1.7.3.14

::= | | | | | | | |

, ,, and 请参考HANA SQL中INSERT , DELETE, UPDATE, REPLACE and UPSERT SQL语句

::= SELECT INTO [] [] [] [{
, … }] [] [] ;

::= [{, }…] 为基础类型变量

3.1.7.3.15

::= OPEN [ ] ;

::= FETCH INTO ;

::= CLOSE ;

Cursor operations

3.1.7.3.16

::= CALL () ;

Calling a procedure

3.1.7.3.17

::= {EXEC | EXECUTE IMMEDIATE} ;

You use EXEC to make dynamic SQL calls.

3.1.7.3.18

::= RETURN [] ;

Return a value from a procedure.

3.1.8 Examples

Example 1 - Creating an SQL Procedure

You create an SQLScript procedure with the following definition.

CREATECOLUMNTABLE“SYSTEM”.”T” (“ID”INTEGER CS_INT,

​ “NAME”VARCHAR(30),

​ “PAYMENT”INTEGER CS_INT) UNLOAD****PRIORITY 5 AUTO MERGE;

insert****into“SYSTEM”.”T”values(1,’a’,10);

insert****into“SYSTEM”.”T”values(2,’b’,20);

insert****into“SYSTEM”.”T”values(3,’c’,30);

CREATE****PROCEDURE orchestrationProc LANGUAGE SQLSCRIPT AS

BEGIN

DECLARE v_id INT;

DECLARE v_name VARCHAR(30);

DECLARE v_pmnt INT;

DECLARE v_msg VARCHAR(200);

DECLARE****CURSOR c_cursor1 (p_payment INT) FOR****SELECT id, name, PAYMENT FROM t

WHERE payment >= p_payment ORDER****BY id ASC;

OPEN c_cursor1(20);

FETCH c_cursor1 INTO v_id, v_name, v_pmnt;

​ v_msg := v_name || ‘ (id ‘ || v_id || ‘) earns ‘ || v_pmnt || ‘ $.’;

select v_msg from dummy;

CLOSE c_cursor1;

end;

Example 2 - Using a result view

创建带返回视图结果的存储过程:

CREATE****PROCEDURE ProcWithResultView(IN id INT, OUT o1 t)

LANGUAGE SQLSCRIPT

READS SQL DATA WITH RESULT VIEW ProcView AS

BEGIN

o1 = SELECT * FROM t WHERE id = :id;

END;

调用存储视图:

select * from ProcView with parameters (‘placeholder’ = (‘

idid

‘ ,’2’ ));

CREATE****PROCEDURE Proc_test(IN id INT,IN name varchar(3),OUT o1 “SYSTEM”.”T_COLUMN”)

LANGUAGE SQLSCRIPT

READS SQL DATA WITH RESULT VIEW Proc_View AS

BEGIN

outt = CE_COLUMN_TABLE(“SYSTEM”.”T_COLUMN”,[id,name,payment]);

–注:过滤条件一定要使用单引号整体引起来;列名一定要使用双引号引起来;

–如果是字符串,则要使用单引号引起来,因为外层有单引号,所以里面要使用两个单引号代表一个单引号

–o1 = CE_PROJECTION(:outt,[id,name,payment],’”ID” = :id AND “NAME” = ‘’:name’’’);

–上面这句等效于下面两句

o1 = CE_PROJECTION(:outt,[id,name,payment],’”ID” = :id’);

o1 = CE_PROJECTION(:o1,[id,name,payment],’”NAME” = ‘’:name’’’);

END;

select * from Proc_View with parameters (‘placeholder’ = (‘

idid

‘ ,’2’ ),’placeholder’ = (‘namename’ ,’b’ ));

Note

Procedures and result views produced by procedures are not connected from the security perspective and therefore do not inherit privileges from each other. The security aspects of each object must be handled separately. For example, you must grant the SELECT privilege on a result view and EXECUTE privilege on a connected procedure.

7a1c08c79f3df8dccd0ae9edda11728b461028ed

Oracle中的translate函数和replace函数的用法

接触到此函数目的是为了判断某一单元格数据是在这里插入代码片否为纯数字,虽然实际来说TRANSLATE()实际不是为了判断数据格式。

translate函数语法:

1
translate(expr, from_string, to_string)

功能:在expr中寻找匹配from_string中符合的字符下标,随后根据下标去to_string中寻找对应的字符替换掉expr中对应下标的字符。

expr:进行处理匹配替换的数据

from_string:需要在expr中寻找匹配的字符

to_string:替换在from_string中找到的expr中对应下标的字符

栗子:

1
2
select translate('ac','ab2','00') from dual;
--return 0c

首先拿出ac中的a去匹配ab2中的字符,他会一个字符一个字符的进行判断。

1
2
3
a==a true      	//a和ab2中的第一个字符比较,结果正确
a==b false //a和ab2中的第二个字符比较,结果错误
a==2 false //a和ab2中的第三个字符比较,结果错误

而其中的a匹配到了ab2中的字符,a在ab2中为第一位,所以也去00中寻找第一位进行替换,这时是0c。

再去匹配第二位的c,而在ab2中没有找到,所以不进行替换。

所以返回的结果为0c。

栗子ii:

1
2
select translate('ac1','abc123','abc') from dual;
--return ac

当to_string比from_string短时,会对多余的位数进行剔除

这里中进行匹配到最后的1时,发现1在abc123中位置为第四位,而通过第四位去替换,去寻找abc的第四位时发现abc没有第四位,这时会将1剔除,返回的结果为ac。

需要注意的是,to_str不能是NULL或者’’,否则会返回空值。

  1. translate也不能用于CLOB,再说得简单一点,也就是
    如果string中的字符如果在from_string中没有,那么返回时被保留
  2. 如果string中的字符是from_string中的”额外字符”,那么返回时被删除
  3. 如果string中的字符在from_string中找到,且在to_string中有相应位置的字符,那么返回时用to_string中的字符替换string中的字符

replace函数

语法:

1
REPLACE(expr, from_string,to_string)

功能:用法和上文中的translate的用法相同,唯一不同的是translate是会对expr中的字符一个一个和from_string进行匹配,而replace却类似于模糊查询like,会在expr中查找包含from_string的部分并且进行替换为to_string。

expr:进行处理匹配替换的数据

from_string:需要在expr中寻找匹配的字符

to_string:替换在from_string中找到的expr中对应下标的字符

栗子:

1
2
3
4
select REPLACE('fgsgswsgs', 'fk' ,'j') 返回值 from dual;
--return fgsgswsgs
select REPLACE('fgsgswsgs', 'sg' ,'eeerrrttt') 返回值 from dual;
--return fgeeerrrtttsweeerrrttts

分析:

第一个例子中由于’fgsgswsgs’中没有与’fk’匹配的字符串,

​ 故返回值仍然是’fgsgswsgs’;

​ 第二个例子中将’fgsgswsgs’中的字符串’sg’全部转换为’eeerrrttt’。

总结:综上所述,replace与translate都是替代函数,

​ 只不过replace针对的是字符串,而translate针对的是单个字符。

和replace函数的区别

1
2
3
4
5
select translate('itmyhome#163%com', '#%', '@.') from dual;
--return itmyhome@163.com

select replace('itmyhome#163%com', '#%', '@.') from dual;
--return itmyhome#163%com

上面的translate函数是将#替换为@,%替换为.

而replace却没有实现此效果,是因为没有找到#%整体的组合

部分引自

53186325_p0

戦いの前夜

开窗函数

排序函数

开窗函数over(),包含三个分析子句:分组(partition by), 排序(order by), 窗口(rows) ,他们的使用形式如下:over(partition by 排序字段 order by 分区字段 rows between 开窗规则)。

开窗函数
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行。

开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,

示例数据:

QQ截图20210312144133

第一大类:聚合开窗函数====》聚合函数(列) OVER (选项)

:sum(),count()等都可以拼接

第二大类:排序开窗函数====》排序函数(列) OVER(选项)

:rank(),row_number()等需要和over一起使用排序函数

不限于此,很多函数都可以配合over(),在这里不做过多介绍

语法:

1
2
3
4
5
6
7
8
9
--select 函数名()over(partition by 需要分区的列名 order by 想排序的列名 rows/range 
--unbounded preceding and unbouned following针对当前所有记录的前一条、后一条记录,也就是表中的所有记录
--unbounded:不受控制的,无限的
--preceding:在...之前
--following:在...之后
-- BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) from 表名
--such as
select *,sum(sage)over(order by sage rows between UNBOUNDED preceding and UNBOUNDED following)
from "student"

分区(partition by ):

功能与group by几乎相同,但group by对于聚合的分组只显示一行数据,并且select后的字段如果其中一个被group by,那么其他字段要么是聚合函数要么也被group by分组聚合。

栗子:分别求男女同学年龄总和

QQ截图20210315093653

而聚合函数搭配over()可以一组返回多行数据,而且其他字段不需要为被分组或被聚合。

排序(order by):

栗子:男女分别根据年龄降序排列

QQ截图20210315100337

没什么需要多说的,这里使用了rank()函数排序,partition by相当于group by,order by还是原意。

注:关于rank()等排序函数请移步其他文章,本文不做说明

栗子ii:男女按照年龄降序分别求出年龄累计

QQ截图20210315135813

这里发生了变化,当使用sum()或count()配合over使用,并且使用partition by和order by,就会根据排序进行逐渐的累加或者求和,可以用于计算各个月份随时间累计数等情况

窗口(rows/range)注:rows可以使用,但是range没研究明白报错:

在Over子句中,使用Rows 或Range 进一步限制分区的数据行,在使用时,必须注意:

必需条件:如果使用Rows 或 Range必须跟在Order by 子句之后,对排序的结果进行限制;
Rows:使用固定的行数来限制分区中的数据行数量;The ROWS clause limits the rows within a partition by specifying a fixed number of rows preceding or following the current row.
Range:使用Value的范围来限制分区中的数据行数量,排序列的重复值,被认为是一个值;The RANGE clause logically limits the rows within a partition by specifying a range of values with respect to the value in the current row.
在分区中,如果排序行不存在重复值,Rows和Range返回的结果是相同的;如果排序行存储在重复值,Rows和Range返回的结果可能不同;
Range子句只能从分区的开始或结尾到当前行开始计算,不能使用 PRECEDING 和 FOLLOWING;
使用在Rows 和 Range子句中的特殊关键字:

UNBOUNDED PRECEDING:指定分区的第一行
UNBOUNDED FOLLOWING:指定分区的最后一行
CURRENT ROW:指定分区的当前数据行
PRECEDING:在分区中,指定当前行之前的数据行数量,UINT_Number是>=0的整数
FOLLOWING:在分区中,指定当前行之后的数据行数量,UINT_Number是>=0的整数

1
2
3
4
--每行数据都会被开窗影响,每行数据都会根据开窗的行数来向上或向下进行函数的操作。
--当上面没有行时上面的行不做影响,下面也没有行时同上。
select *,sum(sage)over(order by sage rows between 前多少行 preceding and 后多少行 following)
from "student"

栗子:对分区中的连续两行计算加和,将每行和下一行进行相加

QQ截图20210315150441

第一行=第一行sage+第二行sage,第二行=第二行sage+第三行sage………..以此类推

图中第五行数据和第十行数据都是分区中的最后一行数据,没有下面的行进行相加所以是原数

–栗子ii:对分区中的当前行向下计算加和,将每行到当前分区最底下的进行相加

Could not execute ‘select *,sum(sage)over(order by sage range between unbounded preceding and unbounded following) …’
SAP DBTech JDBC: [7]: feature not supported: Window frame specification of RANGE not allowed for this window function: line 1 col 10 (at pos 9)

202005241421367251716257711.500x0.jpg.webp

to be continued(多半是鸽了😜

排序函数

排序函数:

排序函数的作用是基于一个结果集返回一个排序值。排序值就是一个数字,这个数字是典型的以1开始且自增长为1的行值。由排序函数来决定排序值。可以使唯一的对于当前结果集,或者某些行数据有相同的排序值。接下来介绍不同的排序函数以及如何使用这些函数。

示例数据:

QQ截图20210312144133

语法:

1
2
3
4
--select 函数名()over(order by 想排序的列名) from 表名
--such as
select rank()over(partition by ssex order by sage desc)
from "student"

注:over()开窗函数用法在此文中不进行介绍

ROW_NUMBER()

定义:ROW_NUMBER()函数作用就是将select查询到的数据进行排序,每一条数据加一个序号,他不能用做于学生年龄的排名,一般多用于分页查询,因为在遇到相同年龄时序号依然会继续自增,而非并列的序号。

栗子:根据年龄降序排列学生

QQ截图20210312145034

ROW_NUMBER()当遇到相同年龄时序号依然会自增

RANK()

定义:RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,与ROW_NUMBER()不同,当存在相同年龄的学生时,ROW_NUMBER()会继续进行排序,他们的序号不相同,而Rank()则不一样,当出现相同的年龄时,他们的排名是一样的,并且会跳过已经占用的序号。

栗子:根据年龄降序排列学生

QQ截图20210312145927

这里第五条数据突然从2号序号跳跃到5号序号,是因为上面已经有四位同学被排序过,按照已经被排序的数据条数就是5号

RANK()当遇到相同年龄时序号时序号不会自增,而是和相同年龄时的序号相同。同时当再次向下排序遇到不同年龄时,会根据已进行排序的条数来跳跃序号。

DENSE_RANK()

定义:DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名,那它和RANK()到底有什么不同那?

栗子:根据年龄降序排列学生

QQ截图20210312150624

dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号,rank值紧接上一次的rank值。在各个分组内,rank()是跳跃排序,有两个第一名时接下来就是第四名,dense_rank()是连续排序,有两个第一名时仍然跟着第二名。

NTILE()

定义:ntile函数可以对序号进行分组处理,将有序分区中的行分发到指定数目的组中。 各个组有编号,编号从一开始。 对于每一个行,ntile 将返回此行所属的组的编号。这就相当于将查询出来的记录集放到指定长度的数组中,每一个数组元素存放一定数量的记录。ntile函数为每条记录生成的序号就是这条记录所有的数组元素的索引(从1开始)。也可以将每一个分配记录的数组元素称为“桶”。ntile函数有一个参数,用来指定桶数。

QQ截图20210312160137

将年龄降序并且平均分为四个桶(区)

  ntile函数的分组依据(约定):

  1、每组的记录数不能大于它上一组的记录数,即编号小的桶放的记录数不能小于编号大的桶。就是说,第1组中的记录数只能大于等于第2组及以后各组中的记录数。

  2、所有组中的记录数要么都相同,要么从某一个记录较少的组(命名为X)开始后面所有组的记录数都与该组(X组)的记录数相同。也就是说,如果有个组,前三组的记录数都是9,而第四组的记录数是8,那么第五组和第六组的记录数也必须是8。

以上为四个排序函数的用法,最后一个可能不算排序,而是根据排序内容分桶,应用场景一般不为排序。而这些排序函数都依赖于over分窗函数,可以看到排序都是在它之中进行的,同时它也可以使用partition by排序的同时分组,类似于group by,也可以根据row和range进行开窗,但这里不过多解释。!

总结:

在使用排名函数的时候需要注意以下三点:

  1、排名函数必须有 OVER 子句。

  2、排名函数必须有包含 ORDER BY 的 OVER 子句。

  3、分组内从1开始排序。

引自[Sql 四大排名函数(ROW_NUMBER、RANK、DENSE_RANK、NTILE)简介]

20200429013947.52ff80ba8cacf5780b8e9e93e02e02ef