ORACLE排序与分析函数
ORACLE_分析函数大全
ORACLE_分析函数大全Oracle分析函数是一种高级SQL函数,它可以在查询中实现一系列复杂的分析操作。
这些函数可以帮助我们在数据库中执行各种数据分析和报表生成任务。
本文将介绍Oracle数据库中的一些常用分析函数。
1.ROW_NUMBER函数:该函数为查询结果中的每一行分配一个唯一的数字。
可以用它对结果进行排序或分组。
例如,可以使用ROW_NUMBER函数在结果集中为每个员工计算唯一的编号。
2.RANK和DENSE_RANK函数:这两个函数用于计算结果集中每个行的排名。
RANK函数返回相同值的行具有相同的排名,并且下一个排名值将被跳过。
DENSE_RANK函数类似,但是下一个排名值不会被跳过。
G和LEAD函数:LAG函数返回结果集中指定列的前一个(上一个)行的值,而LEAD函数返回后一个(下一个)行的值。
这些函数通常用于计算增长率或发现趋势。
4.FIRST和LAST函数:这两个函数用于返回结果集中分组的第一个和最后一个行的值。
可以与GROUPBY子句一起使用。
5.CUME_DIST函数:该函数用于计算给定值的累积分布。
它返回值的累积分布在结果集中的位置(百分比)。
6.PERCENT_RANK函数:该函数用于计算结果集中每个行的百分位数排名。
它返回值的百分位数排名(0到1之间的小数)。
7. NTILE函数:该函数用于将结果集分成指定数量的桶(Bucket),并为每个行分配一个桶号。
通常用于将数据分组为更小的块。
8.LISTAGG函数:该函数将指定列的值连接成一个字符串,并使用指定的分隔符分隔每个值。
可以用它将多个值合并在一起形成一个字符串。
9.AVG、SUM、COUNT和MAX/MIN函数:这些是常见的聚合函数,可以在分析函数中使用。
它们用于计算结果集中的平均值、总和、计数和最大/最小值。
以上只是Oracle数据库中的一些常用分析函数。
还有其他一些分析函数,如PERCENTILE_CONT、PERCENTILE_DISC等可以用于更高级的分析计算。
Oracle分析函数用法详解
Oracle分析函数Oracle分析函数实际上操作对象是查询出的数据集,也就是说不需二次查询数据库,实际上就是oracle实现了一些我们自身需要编码实现的统计功能,对于简化开发工作量有很大的帮助,特别在开发第三方报表软件时是非常有帮助的。
Oracle从8.1.6开始提供分析函数。
一、基本语法oracle分析函数的语法:function_name(arg1,arg2,...)over(<partition-clause> <order-by-clause ><windowing clause>)说明:1.partition-clause 数据记录集分组2.order-by-clause 数据记录集排序3.windowing clause 功能非常强大、比较复杂,定义分析函数在操作行的集合。
有三种开窗方式: range、row、specifying。
二、常用分析函数1. avg(distinct|all expression) 计算组内平均值,distinct 可去除组内重复数据select deptno,empno,sal,avg(sal) over (partition by deptno) avg_sal from t;DEPTNO EMPNO SAL AVG_SAL---------- ---------- ---------- ----------10 7782 2450 2916.666677839 5000 2916.666677934 1300 2916.6666720 7566 2975 21757902 3000 21757876 1100 21757369 800 21757788 3000 217530 7521 1250 1566.666677844 1500 1566.666677499 1600 1566.666677900 950 1566.666677698 2850 1566.666677654 1250 1566.666672.count(<distinct><*><expression>) 对组内数据进行计数3.rank() 和dense_rank()dense_rank()根据 order by 子句表达式的值,从查询返回的每一行,计算和其他行的相对位置,序号从 1 开始,有重复值时序号不跳号。
ORACLE中的ROW_NUMBEROVER分析函数的用法
ORACLE中的ROW_NUMBEROVER分析函数的用法ROW_NUMBER(OVER(是ORACLE数据库中的一个分析函数,用来为结果集中的每一行分配一个唯一的序号。
ROW_NUMBER(OVER(的语法是:ROW_NUMBER( OVER ( [ PARTITION BY expr1 [, expr2, ...] ]ORDER BY clause )其中,PARTITIONBY子句可选,用来指定分区依据的列或表达式;ORDERBY子句用来指定排序的列或表达式。
ROW_NUMBER(OVER(常用在查询结果需要进行分页或者进行排序后获取前几行的场景中。
以下是ROW_NUMBER(OVER(的用法示例:示例1:查询员工表中每个部门的员工数,并按照员工数降序排序。
SELECT department_id, count(*) as employee_count,ROW_NUMBER( OVER (ORDER BY count(*) DESC) as rankFROM employeesGROUP BY department_idORDER BY count(*) DESC;在这个示例中,ROW_NUMBER(OVER(函数根据部门中的员工数进行降序排序,并为每个部门分配一个唯一的序号。
示例2:查询员工表中每个部门的员工数,并按照员工数降序排序,并且只返回前三名。
SELECT department_id, count(*) as employee_count,ROW_NUMBER( OVER (ORDER BY count(*) DESC) as rankFROM employeesGROUP BY department_idWHERE rank <= 3ORDER BY count(*) DESC;在这个示例中,ROW_NUMBER(OVER(函数的结果用于限制查询结果只返回前三名。
示例3:查询员工表中每个部门的员工信息,并按照部门和薪水进行排序。
Oracle分析函数使用总结
Oracle分析函数使用总结1.使用评级函数评级函数(ranking function)用于计算等级、百分点、n分片等等,下面是几个常用到的评级函数:RANK():返回数据项在分组中的排名。
特点:在排名相等的情况下会在名次中留下空位DENSE_RANK():与RANK不同的是它在排名相等的情况下不会在名次中留下空位CUME_DIST():返回特定值相对于一组值的位置:他是“cumulative distribution”(累积分布)的简写PERCENT_RANK():返回某个值相对于一组值的百分比排名NTILE():返回n分片后的值,比如三分片、四分片等等ROW_NUMBER():为每一条分组纪录返回一个数字下面我们分别举例来说明这些函数的使用1)RANK()与DENSE-RANK()首先显示下我们的源表数据的结构及部分数据:SQL> desc all_sales;名称是否为空? 类型----------------------------------------- -------- -----------YEAR NOT NULL NUMBER(38)MONTH NOT NULL NUMBER(38)PRD_TYPE_ID NOT NULL NUMBER(38)EMP_ID NOT NULL NUMBER(38)AMOUNT NUMBER(8,2)SQL> select * from all_sales where rownum<11;YEAR MONTH PRD_TYPE_ID EMP_ID AMOUNT---------- ---------- ----------- ---------- ----------2003 1 1 21 10034.842003 2 1 21 15144.652003 3 1 21 20137.832003 4 1 21 25057.452003 5 1 21 17214.562003 6 1 21 15564.642003 7 1 21 12654.842003 8 1 21 17434.822003 9 1 21 19854.572003 10 1 21 21754.19已选择10行。
Oracle分析函数row_number()over(partitionbyorderby)
Oracle分析函数row_number()over(partitionbyorderby)1、格式row_number() over(partition by 列名1 order by 列名2 desc)2、解析表⽰根据列名1 分组,然后在分组内部根据列名2 排序,⽽此函数计算的值就表⽰每组内部排序后的顺序编号,可以⽤于去重复值与rownum的区别在于:使⽤rownum进⾏排序的时候是先对结果集加⼊伪列rownum然后再进⾏排序,⽽此函数在包含排序从句后是先排序再计算⾏号码.3、实例--分析函数SELECT USER_NAME,SCHOOL,DEPART,ROW_NUMBER() OVER(PARTITION BY USER_NAME ORDER BY SCHOOL, DEPART DESC)FROM USER_M;结果--分析函数SELECT *FROM (SELECT USER_NAME,SCHOOL,DEPART,ROW_NUMBER() OVER(PARTITION BY USER_NAME ORDER BY SCHOOL, DEPART DESC) RNFROM USER_M)WHERE RN = 1;结果--结合分页SELECT *FROM (SELECT ER_NAME,A.SCHOOL,A.DEPART,ROW_NUMBER() OVER(PARTITION BY SCHOOL ORDER BY USER_NAME, DEPART DESC) RNFROM (SELECT * FROM USER_M) AWHERE ROWNUM <= 10)WHERE RN >= 1;结果。
oracle常用的分析函数
oracle常⽤的分析函数常⽤的分析函数如下所列:row_number() over(partition by ... order by ...)rank() over(partition by ... order by ...)dense_rank() over(partition by ... order by ...)count() over(partition by ... order by ...)max() over(partition by ... order by ...)min() over(partition by ... order by ...)sum() over(partition by ... order by ...)avg() over(partition by ... order by ...)first_value() over(partition by ... order by ...)last_value() over(partition by ... order by ...)lag() over(partition by ... order by ...)lead() over(partition by ... order by ...)⼀、Oracle分析函数简介:在⽇常的⽣产环境中,我们接触得⽐较多的是OLTP系统(即Online Transaction Process),这些系统的特点是具备实时要求,或者⾄少说对响应的时间多长有⼀定的要求;其次这些系统的业务逻辑⼀般⽐较复杂,可能需要经过多次的运算。
⽐如我们经常接触到的电⼦商城。
在这些系统之外,还有⼀种称之为OLAP的系统(即Online Aanalyse Process),这些系统⼀般⽤于系统决策使⽤。
通常和数据仓库、数据分析、数据挖掘等概念联系在⼀起。
这些系统的特点是数据量⼤,对实时响应的要求不⾼或者根本不关注这⽅⾯的要求,以查询、统计操作为主。
Oracle分析函数-排序排列(rank、dense_rank、row_number、ntile)
Oracle分析函数-排序排列(rank、dense_rank、row_number、ntile)(1)rank函数返回⼀个唯⼀的值,除⾮遇到相同的数据时,此时所有相同数据的排名是⼀样的,同时会在最后⼀条相同记录和下⼀条不同记录的排名之间空出排名。
(2)dense_rank函数返回⼀个唯⼀的值,除⾮当碰到相同数据时,此时所有相同数据的排名都是⼀样的。
(3)row_number函数返回⼀个唯⼀的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增。
(4)ntile是要把查询得到的结果平均分为⼏组,如果不平均则分给第⼀组。
例如:create table s_score( s_id number(6),score number(4,2));insert into s_score values(001,98);insert into s_score values(002,66.5);insert into s_score values(003,99);insert into s_score values(004,98);insert into s_score values(005,98);insert into s_score values(006,80);selects_id,score,rank() over(order by score desc) rank --按照成绩排名,纯排名,dense_rank() over(order by score desc) dense_rank --按照成绩排名,相同成绩排名⼀致,row_number() over(order by score desc) row_number --按照成绩依次排名,ntile(3) over (order by score desc) group_s --按照分数划分成绩梯队from s_score;排名/排序的时候,有时候,我们会想到利⽤伪列row_num,利⽤row_num确实可以解决某些场景下的问题(但是相对也⽐较复杂),⽽且有些场景下的问题却很难解决。
Oracle之分析函数
Oracle之分析函数⼀、分析函数 1、分析函数 分析函数是Oracle专门⽤于解决复杂报表统计需求的功能强⼤的函数,它可以在数据中进⾏分组然后计算基于组的某种统计值,并且每⼀组的每⼀⾏都可以返回⼀个统计值。
2、分析函数和聚合函数的区别 普通的聚合函数⽤group by分组,每个分组返回⼀个统计值,⽽分析函数采⽤partition by分组,并且每组每⾏都可以返回⼀个统计值。
3、分析函数的形式 分析函数带有⼀个开窗函数over(),包含分析⼦句。
分析⼦句⼜由下⾯三部分组成: partition by :分组⼦句,表⽰分析函数的计算范围,不同的组互不相⼲; ORDER BY:排序⼦句,表⽰分组后,组内的排序⽅式; ROWS/RANGE:窗⼝⼦句,是在分组(PARTITION BY)后,组内的⼦分组(也称窗⼝),此时分析函数的计算范围窗⼝,⽽不是PARTITON。
窗⼝有两种,ROWS和RANGE; 使⽤形式如下:OVER(PARTITION BY xxx PORDER BY yyy ROWS BETWEEN rowStart AND rowEnd) 注:窗⼝⼦句在这⾥我只说rows⽅式的窗⼝,range⽅式和滑动窗⼝也不提。
⼆、OVER() 函数 1、sql 查询语句的 order by 和 OVER() 函数中的 ORDER BY 的执⾏顺序 分析函数是在整个sql查询结束后(sql语句中的order by的执⾏⽐较特殊)再进⾏的操作, 也就是说sql语句中的order by也会影响分析函数的执⾏结果: [1] 两者⼀致:如果sql语句中的order by满⾜分析函数分析时要求的排序,那么sql语句中的排序将先执⾏,分析函数在分析时就不必再排序; [2] 两者不⼀致:如果sql语句中的order by不满⾜分析函数分析时要求的排序,那么sql语句中的排序将最后在分析函数分析结束后执⾏排序。
2、分析函数中的分组/排序/窗⼝分析函数包含三个分析⼦句:分组(partition by),排序(order by),窗⼝(rows/range)窗⼝就是分析函数分析时要处理的数据范围,就拿sum来说,它是sum窗⼝中的记录⽽不是整个分组中的记录,因此我们在想得到某个栏位的累计值时,我们需要把窗⼝指定到该分组中的第⼀⾏数据到当前⾏, 如果你指定该窗⼝从该分组中的第⼀⾏到最后⼀⾏,那么该组中的每⼀个sum值都会⼀样,即整个组的总和。
oracle常用的开窗函数使用技巧
oracle常用的开窗函数使用技巧在数据库操作中,常常需要对数据进行分组、排序、过滤、统计等操作,这时候开窗函数就成为了一种非常有用的技巧。
Oracle是一种支持开窗函数的数据库,他们可以被用于查询、分析、排序、聚合等操作。
下面将为大家介绍几种常见的开窗函数使用技巧。
一、聚合函数实现在数据库中,聚合函数是非常常见的操作,例如SUM、COUNT、AVG等。
在某些情况下,我们需要在查询中同时获得数据的总量或平均值,这时候开窗函数就可以派上用场了。
下面是一个求平均值并加上一个平均值窗口的例子:SELECT name, salary, AVG(salary) OVER () AS average_salary FROM employee结果如下所示:name | salary | average_salary John Smith | 50000 | 66667 Jane Doe | 75000 | 66667 Harry Zheng| 83333 | 66667 Eva Li | 58000 | 66667二、分组函数实现有时候,我们需要按照某些条件来对数据进行分组操作,这就需要使用到分组函数。
例如以下查询就需要按照部门将员工数据进行分组:SELECT department, name, salary, AVG(salary)OVER (PARTITION BY department) AS average_salaryFROM employee结果如下所示:department | name | salary |average_salary IT | John Smith | 50000 |51667 IT | Harry Zheng| 83333 | 51667 HR | Jane Doe | 75000 | 66667 Finance | Eva Li | 58000 | 58000三、分析函数实现分析函数可以帮助我们对数据进行排序和分组。
oracle分组排序汇总笔记
一、相关函数:Group by、Rollup、Cube、Grouping sets、Over、Grouping_id、Grouping、Decode、lag、lead、rank、dense_rank、row_number、count二、初始化数据:-- Create tablecreate table EMPLOYEE(EID NUMBER not null,ENAME V ARCHAR2(20) not null,EADDRESS V ARCHAR2(200) not null,E_DID NUMBER not null,HIRE_DA TE DA TE not null,SALARY NUMBER(8,2) not null,BONUS NUMBER(8,2),BOSS NUMBER)tablespace USERSpctfree 10initrans 1maxtrans 255storage(initial 64minextents 1maxextents unlimited);-- Create/Recreate primary, unique and foreign key constraintsalter table EMPLOYEEadd primary key (EID)using index;--insert contentinsert into EMPLOYEE (EID, ENAME, EADDRESS, E_DID, HIRE_DATE, SALARY, BONUS, BOSS)values (1, '郭芙', '广东', 1, to_date('02-01-2006', 'dd-mm-yyyy'), 2000.5, 100.5, 10);insert into EMPLOYEE (EID, ENAME, EADDRESS, E_DID, HIRE_DATE, SALARY, BONUS, BOSS)values (3, '杨康', '成都', 3, to_date('14-07-2004', 'dd-mm-yyyy'), 3000, null, 10);insert into EMPLOYEE (EID, ENAME, EADDRESS, E_DID, HIRE_DATE, SALARY, BONUS, BOSS)values (9, '杨过', '广东', 1, to_date('02-03-2005', 'dd-mm-yyyy'), 2000, 1000, 10);insert into EMPLOYEE (EID, ENAME, EADDRESS, E_DID, HIRE_DATE, SALARY, BONUS, BOSS)values (10, '小龙女', '广东', 2, to_date('05-04-2000', 'dd-mm-yyyy'), 8000, null, 10);insert into EMPLOYEE (EID, ENAME, EADDRESS, E_DID, HIRE_DATE, SALARY, BONUS, BOSS)values (11, '郭襄', '广东', 3, to_date('01-12-2010', 'dd-mm-yyyy'), 5000, null, 10);insert into EMPLOYEE (EID, ENAME, EADDRESS, E_DID, HIRE_DATE, SALARY, BONUS, BOSS)values (14, '郭靖', '成都', 2, to_date('08-07-2008', 'dd-mm-yyyy'), 4300, null, 14);insert into EMPLOYEE (EID, ENAME, EADDRESS, E_DID, HIRE_DATE, SALARY, BONUS, BOSS)values (15, '黄蓉', '成都', 3, to_date('13-05-2009', 'dd-mm-yyyy'), 1600, 200, 14);commit;三、具体应用:1、group by与rollup:select eaddress a ,ename b,sum(salary) c from employee group by rollup(eaddress, ename)图1分析:如图,这里不光只对第一个字段做了累计,先按(eaddress,ename)分组累计,再按(eaddress)分组累计,最后累计全部类似于:select * from(select eaddress,ename,sum(salary) a from employee group by eaddress,enameunion allselect eaddress,null,sum(salary) from employee group by eaddressunion allselect null,null,sum(salary) from employee)2、group by 与cube;select eaddress a ,ename b,sum(salary) c from employee group by cube(eaddress, ename) order by a,b图2分析:CUBE这里的使用与ROLLUP基本相同,但CUBE的合计更加详细,它能够显示次分组字段的合计信息类似于:select eaddress a,ename b,sum(salary) c from employee group by grouping sets((eaddress,ename),(eaddress),(ename),()) order by a,b3、group by 与grouping setsselect eaddress a ,ename b,sum(salary) c from employee group by grouping sets((eaddress, ename),())图3-1select eaddress a ,ename b,sum(salary) c from employee group by grouping sets((eaddress, ename),(eaddress),())图3-2分析:Group by grouping sets可以应用来指定自己感兴趣的总数组合。
Oracle分析函数sumover介绍
Oracle分析函数sumover介绍其中,sum over函数是一种常用的分析函数,它用于对指定列进行求和计算,并返回每一行的累计总和。
以下是sum over函数的基本语法:```SUM(expression) OVER (PARTITION BY col1 [, col2, ...] ORDER BY col3 [, col4, ...] [ROWS <frame specification>])```其中,expression是要进行求和的列或表达式,col1、col2等是用于分组的列,col3、col4等是用于排序的列,frame specification是用于定义计算总和的范围。
sum over函数的作用可以通过一个简单的示例来说明。
假设我们有一个包含销售订单的表,其中包含订单号、产品名称和销售量等列。
我们想要计算每个产品的累计销售量,可以使用sum over函数来实现:```sqlSELECT order_id, product_name, sales_quantity,SUM(sales_quantity) OVER (PARTITION BY product_name ORDER BYorder_id) AS cumulative_salesFROM sales_orders;```在上述示例中,我们使用了PARTITION BY子句来按照产品名称进行分组,然后使用ORDER BY子句按照订单号进行排序。
通过在SUM函数中使用over子句,我们可以计算每个产品的累计销售量,并将结果作为新的列返回。
除了基本的用法之外,sum over函数还可以与其他函数组合使用,进一步扩展其功能。
例如,我们可以使用sum over函数来计算百分比:```sqlSELECT order_id, product_name, sales_quantity,sales_quantity / SUM(sales_quantity) OVER (PARTITION BY product_name) * 100 AS percentageFROM sales_orders;```在上述示例中,我们使用SUM函数计算每个产品的总销售量,并将结果作为分母,然后将每个销售数量除以总销售量并乘以100,得到每个产品的销售百分比。
Oracle分析函数Over()
Oracle分析函数Over()阅读⽬录⼀、Over()分析函数1、rank()/dense_rank over(partition by ... order by ...)2、min()/max() over(partition by ...)3、lead()/lag() over(partition by ... order by ...) 取前⾯/后⾯第n⾏记录4、FIRST_VALUE/LAST_VALUE() OVER(PARTITION BY ...) 取⾸尾记录5、ROW_NUMBER() OVER(PARTITION BY.. ORDER BY ..) 排序(应⽤:分页)6、sum/avg/count() over(partition by ..)7、 rows/range between … preceding and … following 上下范围内求值rows between … preceding and … following⼆、其他1、NULLS FIRST/LAST 将空值字段记录放到最前或最后显⽰2、NTILE(n)3、keep(dense_rank first/last)回到顶部⼀、Over()分析函数说明:聚合函数(如sum()、max()等)可以计算基于组的某种聚合值,但是聚合函数对于某个组只能返回⼀⾏记录。
若想对于某组返回多⾏记录,则需要使⽤分析函数。
1、rank()/dense_rank over(partition by ... order by ...)说明:over()在什么条件之上; partition by 按哪个字段划分组; order by 按哪个字段排序;注意: (1)使⽤rank()/dense_rank() 时,必须要带order by否则⾮法 (2)rank()/dense_rank()分级的区别: rank(): 跳跃排序,如果有两个第⼀级时,接下来就是第三级。
Oracle数据库分析函数用法
Oracle数据库分析函数⽤法⽬录1、什么是窗⼝函数?2、窗⼝函数——开窗3、⼀些分析函数的使⽤⽅法4、OVER()参数——分组函数5、OVER()参数——排序函数1、什么是窗⼝函数?窗⼝函数也属于分析函数。
Oracle从8.1.6开始提供窗⼝函数,窗⼝函数⽤于计算基于组的某种聚合值,窗⼝函数指定了分析函数⼯作的数据窗⼝⼤⼩,这个数据窗⼝⼤⼩可能会随着⾏的变化⽽变化。
与聚合函数的不同之处是:对于每个组返回多⾏,⽽聚合函数对于每个组只返回⼀⾏基本语法: ‹分析函数› over (partition by ‹⽤于分组的列名› order by ‹⽤于排序的列名›)。
语法中的‹分析函数›主要由序列函数(rank、dense_rank和row_number等组成)与聚合函数(sum、avg、count、max和min等)作为窗⼝函数组成。
从窗⼝函数组成上看,它是group by 和 order by的功能组合,group by分组汇总后改变了表的⾏数,⼀⾏只有⼀个类别,⽽partiition by则不会减少原表中的⾏数。
恰如窗⼝函数的组成,它同时具有分组和排序的功能,且不减少原表的⾏数。
OVER 关键字表⽰把函数当成窗⼝函数⽽不是聚合函数。
SQL 标准允许将所有聚合函数⽤做窗⼝函数,使⽤ OVER 关键字来区分这两种⽤法。
2、窗⼝函数——开窗OVER 关键字后的括号中经常添加选项⽤以改变进⾏聚合运算的窗⼝范围。
如果 OVER 关键字后的括号中的选项为空,则窗⼝函数会对结果集中的所有⾏进⾏聚合运算。
分析函数 over(partition by 列名 order by 列名 rows between 开始位置 and 结束位置)为什么叫开窗呢?因为在over()括号中的,partition() 函数可以将查询到的数据进⾏单独开⼀个窗⼝处理。
譬如,查询每个班级的学⽣的排名情况,查询每个国家的历年⼈⼝等,诸如此类,都是在查询到的每⼀个班级、每⼀个国家中都开⼀个窗⼝,单独去执⾏命令。
oracle最全函数大全(分析函数-聚合函数-转换函数-日期型函数-字符型函数-数值型函数-其他函数)
oracle函数大全(分析函数,聚合函数,转换函数,日期型函数,字符型函数,数值型函数,其他函数)oracle函数大全 (1)oracle分析函数--SQL*PLUS环境 (1)oracle 10g函数大全--聚合函数 (19)oracle 10g函数大全--转换函数 (23)oracle 10g函数大全--日期型函数 (40)oracle 10g函数大全--字符型函数 (45)oracle 10g函数大全--数值型函数 (55)oracle 10g函数大全--其他函数 (58)oracle分析函数--SQL*PLUS环境一、总体介绍1.1.分析函数如何工作语法 FUNCTION_NAME(<参数>,…) OVER (<PARTITION BY 表达式,…> <ORDER BY 表达式 <ASC DESC> <NULLS FIRST NULLS LAST>> <WINDOWING子句>) PARTITION子句ORDER BY子句 WINDOWING子句缺省时相当于RANGE UNBOUNDED PRECEDING1. 值域窗(RANGE WINDOW)RANGE N PRECEDING 仅对数值或日期类型有效,选定窗为排序后当前行之前,某列(即排序列)值大于/小于(当前行该列值–/+ N)的所有行,因此与ORDER BY子句有关系。
2. 行窗(ROW WINDOW)ROWS N PRECEDING 选定窗为当前行及之前N行。
还可以加上BETWEEN AND 形式,例如RANGE BETWEEN m PRECEDING AND n FOLLOWING 函数 AVG(<distinct all> eXPr)一组或选定窗中表达式的平均值 CORR(expr, expr) 即COVAR_POP(exp1,exp2) / (STDDEV_POP(expr1) * STDDEV_POP(expr2)),两个表达式的互相关,-1(反相关) ~1(正相关),0表示不相关COUNT(<distinct> <*> <expr>) 计数COVAR_POP(expr, expr) 总体协方差COVAR_SAMP(expr, expr) 样本协方差CUME_DIST 累积分布,即行在组中的相对位置,返回0 ~ 1DENSE_RANK 行的相对排序(与ORDER BY搭配),相同的值具有一样的序数(NULL计为相同),并不留空序数FIRST_VALUE 一个组的第一个值LAG(expr, <offset>, <default>) 访问之前的行,OFFSET是缺省为1 的正数,表示相对行数,DEFAULT是当超出选定窗范围时的返回值(如第一行不存在之前行)LAST_VALUE 一个组的最后一个值LEAD(expr, <offset>, <default>) 访问之后的行,OFFSET是缺省为1 的正数,表示相对行数,DEFAULT是当超出选定窗范围时的返回值(如最后行不存在之前行)MAX(expr) 最大值MIN(expr) 最小值NTILE(expr) 按表达式的值和行在组中的位置编号,如表达式为4,则组分4份,分别为1 ~ 4的值,而不能等分则多出的部分在值最小的那组PERCENT_RANK 类似CUME_DIST,1/(行的序数 - 1)RANK 相对序数,答应并列,并空出随后序号RATIO_TO_REPORT(expr) 表达式值 / SUM(表达式值)ROW_NUMBER 排序的组中行的偏移STDDEV(expr) 标准差STDDEV_POP(expr) 总体标准差STDDEV_SAMP(expr) 样本标准差SUM(expr) 合计VAR_POP(expr) 总体方差VAR_SAMP(expr) 样本方差VARIANCE(expr) 方差REGR_ xxxx(expr, expr) 线性回归函数REGR_SLOPE:返回斜率,等于COVAR_POP(expr1, expr2) / VAR_POP(expr2) REGR_INTERCEPT:返回回归线的y截距,等于AVG(expr1) - REGR_SLOPE(expr1, expr2) * AVG(expr2)REGR_COUNT:返回用于填充回归线的非空数字对的数目REGR_R2:返回回归线的决定系数,计算式为:If VAR_POP(expr2) = 0 then return NULLIf VAR_POP(expr1) = 0 and VAR_POP(expr2) != 0 then return 1If VAR_POP(expr1) > 0 and VAR_POP(expr2 != 0 thenreturn POWER(CORR(expr1,expr),2)REGR_AVGX:计算回归线的自变量(expr2)的平均值,去掉了空对(expr1, expr2)后,等于AVG(expr2)REGR_AVGY:计算回归线的应变量(expr1)的平均值,去掉了空对(expr1, expr2)后,等于AVG(expr1)REGR_SXX:返回值等于REGR_COUNT(expr1, expr2) * VAR_POP(expr2)REGR_SYY:返回值等于REGR_COUNT(expr1, expr2) * VAR_POP(expr1)REGR_SXY: 返回值等于REGR_COUNT(expr1, expr2) * COVAR_POP(expr1, expr2) 首先:创建表及接入测试数据。
oracle分组排序
分组函数oracle分析函数十分强大,我们只要掌握这些方法,更直接的说法就是知道这些分析函数的作用就能完成很多工作。
下边贴出这些函数,及简单应用。
其中我想对lag()和lead()函数坐下说明:lag()本身是延后的意思也就是延后出现某列的数,而lead()有引领、领先的意思也就是提前几行显示某列数据RANK()dense_rank()【语法】RANK ( ) OVER ( [query_partition_clause] order_by_clause )dense_RANK ( ) OVER ( [query_partition_clause] order_by_clause )【功能】聚合函数RANK 和dense_rank 主要的功能是计算一组数值中的排序值。
【参数】dense_rank与rank()用法相当,【区别】dence_rank在并列关系是,相关等级不会跳过。
rank则跳过rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)dense_rank()l是连续排序,有两个第二名时仍然跟着第三名。
【说明】Oracle分析函数【示例】聚合函数RANK 和dense_rank 主要的功能是计算一组数值中的排序值。
在9i版本之前,只有分析功能(analytic ),即从一个查询结果中计算每一行的排序值,是基于order_by_clause子句中的value_exprs指定字段的。
其语法为:RANK ( ) OVER ( [query_partition_clause] order_by_clause )在9i版本新增加了合计功能(aggregate),即对给定的参数值在设定的排序查询中计算出其排序值。
这些参数必须是常数或常值表达式,且必须和ORDER BY子句中的字段个数、位置、类型完全一致。
其语法为:RANK ( expr [, expr]... ) WITHIN GROUP( ORDER BYexpr [ DESC | ASC ] [NULLS { FIRST | LAST }][, expr [ DESC | ASC ] [NULLS { FIRST | LAST }]]...)例子1:有表Table内容如下COL1COL21 12 13 23 14 14 25 25 26 2分析功能:列出Col2分组后根据Col1排序,并生成数字列。
ORACLE_分析函数大全
ORACLE_分析函数大全1.SUM:计算指定列的总和。
用法:SUM(column) OVER (PARTITION BY expression ORDER BY expression)2.AVG:计算指定列的平均值。
用法:AVG(column) OVER (PARTITION BY expression ORDER BY expression)3.COUNT:计算指定列的记录数。
用法:COUNT(column) OVER (PARTITION BY expression ORDER BY expression)4.MAX:计算指定列的最大值。
用法:MAX(column) OVER (PARTITION BY expression ORDER BY expression)5.MIN:计算指定列的最小值。
用法:MIN(column) OVER (PARTITION BY expression ORDER BY expression)6.FIRST_VALUE:计算指定列的第一个值。
用法:FIRST_VALUE(column) OVER (PARTITION BY expression ORDER BY expression)ST_VALUE:计算指定列的最后一个值。
用法:LAST_VALUE(column) OVER (PARTITION BY expression ORDER BY expression)8.LEAD:返回指定行后的值。
用法:LEAD(column, offset, default) OVER (PARTITION BY expression ORDER BY expression)G:返回指定行前的值。
用法:LAG(column, offset, default) OVER (PARTITION BY expression ORDER BY expression)10.RANK:计算指定列的排名(相同值有相同的排名,相同排名后续排名跳过)。
Oracle分析函数RANK(),ROW_NUMBER(),LAG()等的使用方法
Oracle分析函数RANK(),ROW_NUMBER(),LAG()等的使⽤⽅法ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2)表⽰根据COL1分组,在分组内部根据 COL2排序⽽这个值就表⽰每组内部排序后的顺序编号(组内连续的唯⼀的)RANK() 类似,不过RANK 排序的时候跟派名次⼀样,可以并列2个第⼀名之后是第3名LAG 表⽰分组排序后,组内后⾯⼀条记录减前⾯⼀条记录的差,第⼀条可返回 NULLBTW: EXPERT ONE ON ONE 上讲的最详细,还有很多相关特性,⽂档看起来⽐较费劲row_number()和rownum差不多,功能更强⼀点(可以在各个分组内从1开时排序)rank()是跳跃排序,有两个第⼆名时接下来就是第四名(同样是在各个分组内)dense_rank()l是连续排序,有两个第⼆名时仍然跟着第三名。
相⽐之下row_number是没有重复值的lag(arg1,arg2,arg3):arg1是从其他⾏返回的表达式arg2是希望检索的当前⾏分区的偏移量。
是⼀个正的偏移量,时⼀个往回检索以前的⾏的数⽬。
arg3是在arg2表⽰的数⽬超出了分组的范围时返回的值。
SQL> set pagesize 100;SQL> select rownum from emp;ROWNUM----------1234567891011121314已选择14⾏。
已⽤时间: 00: 00: 00.10SQL> select deptno,row_number() over(partition by deptno order by sal) from emp order by deptno;DEPTNO ROW_NUMBER()OVER(PARTITIONBYDEPTNOORDERBYSAL)---------- ---------------------------------------------10 12320 1234530 123456已选择14⾏。
Oracle递归查询与常用分析函数
Oracle递归查询与常⽤分析函数 最近学习oracle的⼀些知识,发现⾃⼰sql还是很薄弱,需要继续学习,现在总结⼀下哈。
(1)oracle递归查询 start with ... connect by prior ,⾄于是否向上查询(根节点)还是向下查询(叶节点),主要看prior后⾯跟的字段是否是⽗ID。
向上查询:select * from test_tree_demo start with id=1 connect by prior pid=id 查询结果: 向下查询:select * from test_tree_demo start with id=3 connect by prior id=pid 如果要进⾏过滤,where条件不能放在connect by 后⾯,如下:select * from test_tree_demo where id !=4 start with id=1 connect by prior pid=id (2)分析函数- over( partition by ) 数据库中的数据如下:select * from testemp1 select deptno,ename,sal,sum(sal)over() deptsum from testemp1 如果over中不加任何条件,就相当于sum(sal),显⽰结果如下: ⼀般over都是配合partition by order by ⼀起使⽤,partition by 就是分组的意思。
下⾯看个例⼦:按部门分组,同个部门根据姓名进⾏⼯资累计求和。
select deptno,ename,sal,sum(sal)over(partition by deptno order by ename) deptsum from testemp1,显⽰如下: 其实统计各个部门的薪⽔总和,可以使⽤group by实现,select deptno,sum(sal) deptsum from testemp1 group by deptno,结果如下: 但是,使⽤group by 的时候查询出来的字段必须是分组的字段或者聚合函数。
oracle的排序函数
oracle的排序函数Oracle是一个强大的数据库管理系统,其拥有多种排序函数,可以帮助用户对查询结果进行排序。
在本文中,我们将介绍Oracle中常用的排序函数及其用法。
1. ORDER BYORDER BY语句是最常用的排序函数之一。
它可以按照指定的列对查询结果进行升序或降序排序。
例如,以下代码将结果按照salary列进行降序排序:SELECT * FROM employees ORDER BY salary DESC;ORDER BY语句还可以指定多个列作为排序的依据。
以下代码将结果按照department_id和salary两列进行升序排序:SELECT * FROM employees ORDER BY department_id ASC, salary ASC;2. NULLS FIRST/NULLS LAST当某一列存在NULL值时,ORDER BY语句默认将NULL值排在结果集的最后面。
如果需要将NULL值排在结果集的最前面,则可以使用NULLS FIRST关键字。
以下代码将结果按照salary列进行升序排序,并将NULL值排在最前面:SELECT * FROM employees ORDER BY salary ASC NULLS FIRST;同理,如果需要将NULL值排在结果集的最后面,则可以使用NULLS LAST关键字。
3. RANKRANK函数可以为某一列中的值进行排名。
例如,以下代码将employees表中的salary列按照值的大小进行排名:SELECT emp_name, salary, RANK() OVER (ORDER BY salary DESC) rank FROM employees;RANK函数默认按照升序排名,如果需要按照降序排名,则可以在ORDER BY语句中指定DESC关键字。
4. DENSE_RANKDENSE_RANK函数与RANK类似,区别在于它不会出现排名相同的情况。
oracle高级用法,decode排序,over(partitionbyxorderbyy。。。
oracle⾼级⽤法,decode排序,over(partitionbyxorderbyy。
场景 01 (IN 语句排序 decode() 函数):1,我们在查询中会经常使⽤这样的⽤法, select * from table_name t where t.id in (1, 3, 7, 9),这是⼀条查询表中 id 为 1, 3, 7, 9 的数据现在我们加上⼀个需求,要求查出来的数据的顺序和括号内 id 的顺序⼀致,有⼈会说直接 order by t.id 啊,多简单,那假设顺序是乱的呢?⼜假如 id 不是数字,⽽是字符串呢?如 select * from table_name t where t.id in (1, 13, 7, 9) 或者 select * from table_name t where t.id in (‘hjkhjk’, 'sfhjsf', 'sdasda', 'dasdad')2,这时候排序就会很⿇烦,oracle 数据库为我们提供了⼀个强⼤的函数 decode,具体⽤法如下:select * from table_name t where t.id in (1, 3, 7, 9) order by decode (t.id, 1, 1, 3, 2, 7, 3, 9, 4)其中 decode 函数的结果作为 order by 的内容,括号内的参数为(排序字段,值,顺序,值,顺序……),其中,顺序值越⼩,排序越靠前场景 02 (分组排序查询,开窗函数 OVER (PARTITION BY COL1 ORDER BY COL2) ):1,平时做项⽬的时候,我们会经常遇到这种情况,假设⼀张表,每⼀天都会给表中的每⼀个种类添加⼀条数据,现在我们要求根据某个⽇期查询出所有种类的对应数据,这很简单,如 select * from table_name t where t.date = '20190101'2,接下来我们增加难度,要求如果该种类当前查询的⽇期不存在数据,那么取最近的前⼀个有数据的⽇期下的对应数据,通俗点说就是我们要查 20190101 这个⽇期下各种类的数据,但是 A 种类该⽇期没数据,那么就把⽇期提前,⽐如 20181231,如果还没有,就查 20191230,直到找到有数据的⽇期为⽌3,这时候有⼈会说,我们可以先查出每个种类下⼩于等于查询⽇期有数据的最⼤⽇期,在查询数据,这种⽅式可⾏,但是如果表中有⼏千⼏万个种类,这回对性能造成很⼤的压⼒4,这时我们会想到我们要是能把数据根据种类分组,然后按时间倒序取每个分组的第⼀条,不就 OK 了吗?这是我们就要⽤到 oracle 为我们提供的强⼤分析函数,也叫开窗函数 OVER(PARTITION BY X ORDER BY Y DESC)该函数⼀般好结合 ROW_NUMBER() 这个获取序号的函数⼀起结合起来,作为 select 的查询字段使⽤,如:select row_number() over(partition by x order by y desc) rn …… (这种⽅式获取的 rn 就是排序之后的序号)5,其中 PARTITION BY X 是根据 X 字段分组,ORDER BY Y DESC 根据 Y 排序, ROW_NUMBER() 在分组排序完成之后,为每个分组中的数据逐条添加序号,每个分组之间互不⼲扰,都是从 1 开始往后排,这是后我们直接取⾏号为 1 的数据,就完美的完成了 2 提出的需求具体如下,⼀个简单的例⼦6,更多关于开窗函数的⽤法请参考。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
--已知:两种排名方式(分区和不分区):使用和不使用partition
--两种计算方式(连续,不连续),对应函数:dense_rank,rank
语法:
rank()over(order by排序字段顺序)
rank()over(partition by分组字段order by排序字段顺序)
1.顺序:asc|desc名次与业务相关:
示例:找求优秀学员:成绩:降序迟到次数:升序
2.分区字段:根据什么字段进行分区。
问题:分区与分组有什么区别?
·分区只是将原始数据进行名次排列(记录数不变),
·分组是对原始数据进行聚合统计(记录数变少,每组返回一条),注意:聚合。
rank()与dense_rank():非连续排名与连续排名(都是简单排名)
·查询原始数据:学号,姓名,科目名,成绩
select*from t_score;
S_ID S_NAME SUB_NAME SCORE
1张三语文80.00
2李四数学80.00
1张三数学0.00
2李四语文50.00
3张三丰语文10.00
3张三丰数学
3张三丰体育120.00
4杨过JAVA90.00
5mike c++80.00
3张三丰Oracle0.00
4杨过Oracle77.00
2李四Oracle77.00
·查询各学生科目为Oracle排名(简单排名)
select sc.s_id,sc.s_name,sub_name,sc.score,rank()over(order by score desc)名次from t_score sc where sub_name='Oracle';
S_ID S_NAME SUB_NAME SCORE名次
4杨过Oracle77.001
2李四Oracle77.001
3张三丰Oracle0.003
·对比:rank()与dense_rank():非连续排名与连续排名(都是简单排名)
S_ID S_NAME SUB_NAME SCORE名次
4杨过Oracle77.001
2李四Oracle77.001
3张三丰Oracle0.002
·查询各学生各科排名(分区排名)
select sc.s_id,sc.s_name,sub_name,sc.score,rank()over(partition by sub_name order by score desc)名次from t_score sc
S_ID S_NAME SUB_NAME SCORE名次
4杨
过JAVA90.001
4杨
过Oracle77.001
2李
四Oracle77.001
3张三丰Oracle0.003
5mike
c++80.001
3张三丰数学1
2李
四数学80.002
1张
三数学0.003
3张三丰体育120.001
1张
三语文80.001
2李
四语文50.002
3张三丰语文10.003
·查询各科前2名(分区排名)
select*from(select sc.s_id,sc.s_name,sub_name,sc.score,dense_rank() over(partition by sub_name order by score desc)名次from t_score sc) x where x.名次<=2;
S_ID S_NAME SUB_NAME SCORE名次
4杨过JAVA90.001
4杨过Oracle77.001
2李四Oracle77.001
3张三丰Oracle0.002
2.oracle分析函数row_number()over()使用
row_number()over([partition by col1]order by col2))as别名
表示根据col1分组,在分组内部根据col2排序
而这个“别名”的值就表示每组内部排序后的顺序编号(组内连续的唯一的),[partition by col1]可省略。
、select deptno,ename,sal,
sum(sal)over(order by ename)累计,--按姓名排序,并将薪水逐个累加
sum(sal)over()总和,--此处sum(sal)over()等同于sum(sal),求薪水总和
100*round(sal/sum(sal)over(),4)"份额(%)"--求每个人的薪水占总额的比例,小数点后保留2位,括号和百分号为特殊符号,所以需要“”
from emp
结果如下:
2、select deptno,ename,sal,
sum(sal)over(partition by deptno order by ename)部门连续求和,--partition by deptno先按部门分组,再按姓名排序,并将薪水逐个累加
sum(sal)over(partition by deptno)部门总和,--每个部门的薪水总和
100*round(sal/sum(sal)over(partition by deptno),4)"部门份额(%)",--每个员工在各自部门的薪水比例sum(sal)over(order by deptno,ename)连续求和,--所有部门的薪水"连续"求和
sum(sal)over()总和,--此处sum(sal)over()等同于sum(sal),所有员工的薪水总和
100*round(sal/sum(sal)over(),4)"总份额(%)"--求每个人的薪水占总额的比例
from emp
结果如下:
3、select deptno,ename,sal,sum(sal)over(partition by deptno order by sal)dept_sum,--根据部门分组,再按部门内的个人薪水排序,逐个累加。
sum(sal)over(order by deptno,sal)sum--按部门排序,将薪水逐个累加。
from emp;
结果如下:
4、部门从大到小排列,部门里各员工的薪水从高到低排列
select deptno,ename,sal,
sum(sal)over(partition by deptno order by deptno desc,sal desc)dept_sum,--按部门分组后,按部门和薪水降序排
sum(sal)over(order by deptno desc,sal desc)sum--按部门和薪水降序排
from emp;
结果如下:
5、将各部门的员工按薪水排序
select ename,job,deptno,sal,(row_number()over(partition by deptno order by sal desc))as排名--先按部门分组,再在部门中按薪水降序排名
from scott.emp
结果如下:
6、查找各部门中薪水最高的前2位
select ename,job,deptno,sal,排名from
(select ename,job,deptno,sal,(row_number()over(partition by deptno order by sal desc))as排名
from scott.emp--先将各部门的员工按薪水排序,再在结果中取出需要的部分
)where排名<=2;
结果如下:
7、如果已经在over()中进行过分组,在"...from emp;"后面不要加order by子句。