1. row_number() over()
ROW_NUMBER() OVER(PARTITION BY COLUMN1 ORDER BY COLUMN2 [desc])
根据column1分组,根据column2排序
2.具体事例
如下,我们通过具体实例进行理解分析。
有如下一张表:
create table LJB_TEST
dep NUMBER,
name VARCHAR2(50),
salary NUMBER
insert all
into ljb_test values('1','start','5000')
into ljb_test values('1','ha','5000')
into ljb_test values('1','end','4000')
into ljb_test values('1','begin','4500')
into ljb_test values('2','ri','4000')
into ljb_test values('2','zhou','6000')
into ljb_test values('2','yue','3000')
into ljb_test values('3','kettle','4000')
into ljb_test values('3','oracle','4000')
into ljb_test values('3','hive','4000')
into ljb_test values('3','mysql','4000')
into ljb_test values('3','plsql','5000')
select 1 from dual
commit;
我们有如下需求:
2.1.计算每个部门薪水值前二的的人员。
自然的,我们根据部门分组,根据薪水降序,取前两个。
我们通过SQL实现上述想法。
select * from
select
row_number() over(partition by dep order by salary desc) rn
from ljb_test t
where t.rn<=2
不过,我们很自然的发现,很多人的薪水是相同的,因而,实际上薪水值前二的员工并不代表是两个员工。也就是说,我们要查的是薪水>=某个值的记录。
因此,我们将自己的想法通过SQL实现。
with tmp
select dep,salary from
select
dep,salary,
row_number() over(partition by dep order by salary desc) rn
from ljb_test t
where t.rn=2
select
from ljb_test t
inner join
on t.dep = tmp.dep
and t.salary>=tmp.salary
order by t.dep,t.salary desc
2.2.计算前百分之几。
如下,我们需要计算每个部门薪水前50%的员工信息,且如果不满两人,取第一个人薪水。
这个问题的核心就是找出每组的50%的分水岭(前10%的逻辑一样)。
如下:
with tmp as
select
dep,salary,
row_number() over(partition by dep order by salary desc) rn
from ljb_test t
select tmp.dep,tmp.salary
from tmp
inner join
select tmp.dep,tmp.salary
from tmp
--2.关联获得50%的薪水值
inner join
--1.算出前50%的每组的row_number()
select t.dep, round(case when count*0.5 end,0) ct
from ljb_test t
group by t.dep
on tmp.dep = tt.dep and tmp.rn = tt.ct
on tmp.dep = ttt.dep and tmp.salary >= ttt.salary
注意:在使用group by时,select xx中的xx不能单独出现,必须要在gruop by中出现,要不然plsql就会提示这个语句不是一个分组语句。2,rank() (跳跃排序,如果有两个第一级别时,也会将两个第一级都显示出来,然后再显示第三级别)通过这种方式,可以用来查询同一个分组的并且按照一定顺序来排列的,可以获取其中第几个顺序。group by 在进行分组之后不能够进行排序,而partition by可以进行排序。3,dense_rank()(连续排序,如果有两个第一级别时,接下来是第二级)
现在我们的需求是查询出来两个班级的前三名可以通过以下:
之前我的想法是根据分数排序然后取三条,后面发现如果分数一致的话,比如有3个人并列第一名,则这样的写法就完全不满足需求,所以我们可以通过over开窗函数来实现上面的要求
SELECT * FROM ( SELECT Name ,Score ,ClassId ,RANK() OVER (...
这里记录一个问题在MySQL中,我们要查看前3条记录的话,是使用limitselect *from t_student order by s_id limit 3;简单的分页也可以使用力limit来完成select *from t_student order by s_id limit 3 offset 3;这都比较常见,如果我们想要获取数据的前10%呢?在SQLServer中,我们可以直接使用t...
击关注上方“SQL数据库开发”,设为“置顶或星标”,第一时间送达干货SQL专栏SQL基础知识第二版SQL高级知识第二版最近帮业务部门梳理业务报表,其中有个需求是就算某指标等待时间最长的前百...
1. 常用分析函数下表列出了一些分析函数以及描述信息:分析函数描述RANK返回数据项在分区中的排名。排名值序列可能会有间隔DENSE_RANK返回数据项在分区中的排名。排名值序列是连续的,不会有间隔PERCENT_RANK计算当前行的百分比排名ROW_NUMBER确定分区中当前行的序号CUME_DIST计算分区中当前行的相对排名NTILE()将每个分区的行尽可能均匀地划分为指定数量的分组2. 语法
sqlserver2005有关键字ntile(x)和over(partition by.. order by..)子句配合. 比如获取每个表的前10%个字段。 select id,name,colid,rn from( select *,rn=ntile(10) over(partition
一、窗口函数简介窗口函数基本语法:<窗口函数> OVER (PARTITION BY <用户分组的列名> ORDER BY <用户排序的列名>)<窗口函数>可使用一下两种函数:专用窗口函数:rank,dense_rank,row_number。聚合函数:sum,avg,count,max,min。窗口函数是对where或者group by 子句处理后...