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<1 then 1 else 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 子句处理后...