高级函数_分析函数与窗口函数

高级函数_分析函数与窗口函数

分析函数往往与窗口函数一起使用,over()为窗口函数

一、分析函数

1.01、排名

分析函数中的排名函数可以针对窗口中的记录生成排序序号,常用的排名函数有:rank()、dense_rank()、row_number()

语句:select * from employee;

EMP_ID                     EMP_NAME                 EMP_SALARY

------------------------ ------------------------------ ----------------------

0001                           张三                           5000

0002                           李四                           4500

0003                           赵飞                           6000

0004                           韩明                           4500

0005                           王兰                           4500

0006                           李丽                           6000

语句:select emp_name,rank()over(order by emp_salary) position from employee;

EMP_NAME          POSITION

---------------------  ----------------------

王兰                           1

李四                           1

韩明                           1

张三                           4

李丽                           5赵飞                           5

rank()函数对于相同排名的记录,会返回相同的排序序号,当出现多个排名 相同的记录时,下一排名序号,将根据前一排名个数进行跳跃,如里面没有出现2和3,直接跳到4

语句:select emp_name,dense_rank()over(order by emp_salary) position from employee;

EMP_NAME             POSITION

------------------------ ----------------------

王兰                           1

李四                           1

韩明                           1

张三                           2

李丽                           3

赵飞                           3

dense_rank()函数对于相同排名的记录,会返回相同的排序序号,当出现多个排名 相同的记录时,不会进行跳跃

语句:select emp_name,row_number() over(order by emp_salary) position from employee;

EMP_NAME               POSITION

------------------------ ----------------------

王兰                           1

李四                           2

韩明                           3

张三                           4

李丽                           5

赵飞                           6row_number()函数每条记录会存在唯一的排序序号

二、分区窗口

利用partition by 可以指定 分区窗口

语句: select * from employee;

EMP_ID             EMP_NAME      EMP_SALARY    EMP_DEPARTMENT

-------------------- ----------------- ---------------------- --------------------

0001                 张三                 5000                   设计部

0002                 李四                 4500                   工程部

0003                 赵飞                 6000                   项目部

0004                 韩明                 4500                   项目部

0005                 王兰                 4500                   工程部

0006                 李丽                 6000                   项目部

语句:select t.*,dense_rank() over(partition byemp_department order by emp_salary) position from employee t order by t.emp_id;

EMP_ID              EMP_NAME         EMP_SALARY           EMP_DEPARTMENT       POSITION

-------------------- -------------------- ---------------------- -------------------- -                 ---------------------

0001                   张三                      5000                           设计部                               1

0002                   李四                      4500                           工程部10003                   赵飞                      6000项目部20004                   韩明                      4500项目部10005                   王兰                      4500工程部10006                   李丽                      6000项目部2

分区内可以求和

语句:select t.*,sum(emp_salary)over(partition byemp_department ) position from employee t order by t.emp_id;

EMP_ID               EMP_NAME             EMP_SALARY           EMP_DEPARTMENT       TOTAL_SALARY

-------------------- -------------------- ----------------------           --------------------                   ---------------------

0001                     张三                        5000                           设计部                               5000

0002李四4500工程部9000

0003赵飞6000项目部16500

0004韩明4500项目部16500

0005王兰4500工程部9000

0006李丽6000项目部16500

三、窗口子句

可以使用窗口子句来进一步控制窗口的范围,包含两类:rows和range

3.01、rows子句

rows子句以当前记录为参照,可以向前向后推移,形成新的结果集

语句:select emp_id,emp_name,emp_salary,sum(emp_salary) over(order by emp_id rows between 1 preceding and 1 following) total_salary from employee;

EMP_ID               EMP_NAME             EMP_SALARY         TOTAL_SALARY

-------------------- -------------------- ----------------------           ----------------------

0001                     张三                         5000                          9500

0002李四450015500

0003赵飞600015000

0004韩明450015000

0005王兰450015000

0006李丽600010500

rows子句因为和位置有关,必须使用order by排序,否则报错

3.02、range子句range子句按照列值进行窗口的进一步限制

语句:select emp_id,emp_name,emp_salary,count(1) over(order by emp_salary range between 300 preceding and 400 following) total_count from employee;

EMP_ID               EMP_NAME             EMP_SALARY             TOTAL_COUNT

-------------------- -------------------- ----------------------               ----------------------

0005                 王兰                            4500                               3

0002                 李四450030004                 韩明450030001                 张三500010006                 李丽600020003                 赵飞60002

3.03、unbouned和 current row

unbouned表示没有任何限制,current row代表当前行

四、主要的分析函数

分析函数作用对象为窗口函数所捕获的记录集合

4.01 、first_value()函数的使用first_value()函数用于获取窗口函数所捕获的记录集中的第一条记录,并根据第一条记录返回返回表达式参数的值

语句: select * from employee;

EMP_ID             EMP_NAME      EMP_SALARY    EMP_DEPARTMENT

-------------------- ----------------- ---------------------- --------------------

0001                 张三                 5000                   设计部

0002                 李四                 4500                   工程部

0003                 赵飞                 6000                   项目部

0004                 韩明                 4500                   项目部

0005                 王兰                 4500                   工程部

0006                 李丽                 6000                   项目部

语句:select distinctemp_department,first_value(emp_name) over(partition by emp_department order by emp_salary)minname,

first_value(emp_salary) over(partition by emp_department order by emp_salary)minsalary  from employee;

EMP_DEPARTMENT       MINNAME              MINSALARY

--------------------                -------------------- ----------------------

设计部                                 张三                     5000

项目部韩明4500

工程部李四4500

备注:distinct关键字是必要的,查询每部门工资最少的人 ,人名和工资都要用first_value()函数,每一列都是一个结果集,互不影响,若有一个不加,不加的会显示所有的值,结果如下:

语句:select distinct emp_department, first_value(emp_name) over(partition by emp_department order by emp_salary) minname,emp_salary from employee;

EMP_DEPARTMENT       MINNAME              EMP_SALARY

--------------------               -------------------- ----------------------

工程部                               李四                     4500

设计部张三5000项目部韩明4500

项目部韩明6000

4.02 、last_value()函数的使用

last_value()函数返回窗口中的最后一条记录的相关信息

语句:select distinct last_value(emp_name) over(partition by emp_department order by emp_salary rows between unbounded preceding and unbounded following) maxname,emp_department,

last_value(emp_salary) over(partition by emp_department order by emp_salaryrows between unbounded preceding and unbounded following) maxsalary  from employee;

MAXNAME              EMP_DEPARTMENT       MAXSALARY

-------------------- --------------------                  ----------------------

张三                      设计部                                5000

赵飞项目部6000李四工程部4500

备注:窗口函数中必须使用rows between unbounded preceding and unbounded following,因为默认情况下,order by 窗口为第一条记录至当前记录,对于order by 子句,如果没有显示指定rows和range子句,则相当于使用了rows between unbounded preceding and current row following或者range between unbounded preceding andcurrent rowfollowing,当排序后存在相同的排名,则所有相同的记录放到被刷选的窗口中,值不同会放到不同的窗口,未使用的结果如下:

语句:select distinct last_value(emp_name) over(partition by emp_department order by emp_salary) maxname,emp_department,

last_value(emp_salary) over(partition by emp_department order by emp_salary) maxsalary  from employee;

MAXNAME              EMP_DEPARTMENT       MAXSALARY

-------------------- --------------------                ----------------------

张三                       设计部                              5000

韩明项目部4500赵飞项目部6000王兰工程部4500

4.03 、lead()函数的使用

lead()函数对于通过排序之后的窗口集合,lead()函数自当前记录向下推移,获得新的记录

语法:lead(表达式,偏移量,替换值) 其中替换值是当无法获取新纪录时,用该值替换

语句:select emp_id,emp_name,emp_salary,emp_department from employee order by emp_id;

EMP_ID               EMP_NAME             EMP_SALARY             EMP_DEPARTMENT

-------------------- -------------------- ---------------------- --------------------

0001                 张三                 5000                   设计部

0002                 李四                 4500                   工程部

0003                 赵飞                 6000                   项目部

0004                 韩明                 4500                   项目部

0005                 王兰                 4600                   工程部

0006                 李丽                 6000                   项目部

语句:select emp_id,emp_name,emp_salary,emp_department,lead(emp_name,1,'无') over(partition by emp_department order by emp_salary) pre_name from employee order by emp_id;

EMP_ID               EMP_NAME             EMP_SALARY             EMP_DEPARTMENT       PRE_NAME

-------------------- -------------------- ---------------------- -------------------- --------------------

0001                 张三                 5000                   设计部               无

0002                 李四                 4500                   工程部               王兰

0003                 赵飞                 6000                   项目部               无

0004                 韩明                 4500                   项目部               李丽

0005                 王兰                 4600                   工程部               无0006                 李丽                 6000                   项目部               赵飞

4.04 、lag()函数的使用

lag()函数与lead()函数具有相同的语法规则,在排序之后,lag()函数自当前记录向上搜索

语法:select emp_id,emp_name,emp_salary,emp_department,lag(emp_name,1,'无') over(partition by emp_department order by emp_salary) pre_name from employee order by emp_id;

EMP_ID               EMP_NAME             EMP_SALARY             EMP_DEPARTMENT       PRE_NAME

-------------------- -------------------- ---------------------- -------------------- --------------------

0001                 张三                 5000                   设计部               无

0002                 李四                 4500                   工程部               无

0003                 赵飞                 6000                   项目部               李丽

0004                 韩明                 4500                   项目部               无

0005                 王兰                 4600                   工程部               李四

0006                 李丽                 6000                   项目部               韩明

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容