• oracle排序使用,很多中函数,不同的效果


    参考原文:http://blog.csdn.net/wanglipo/article/details/6954915

    row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的).   

          与rownum的区别在于:使用rownum进行排序的时候是先对结果集加入伪列rownum然后再进行排序,而此函数在包含排序从句后是先排序再计算行号码.  row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开时排序).  

          rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内).  

          dense_rank()l是连续排序,有两个第二名时仍然跟着第三名。相比之下row_number是没有重复值的 .  

          lag(arg1,arg2,arg3): arg1是从其他行返回的表达式 arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。 arg3是在arg2表示的数目超出了分组的范围时返回的值。

    create table a ( id number(8) not null, val number(8) ) /

    insert into a(id,val) values(1,5);

    insert into a(id,val) values(2,8);

    insert into a(id,val) values(3,8);

     insert into a(id,val) values(5,8);

     insert into a(id,val) values(9,6);

    insert into a(id,val) values(11,6);

    insert into a(id,val) values(22,8);

    insert into a(id,val) values(40,8);

     insert into a(id,val) values(41,5);

    commit;

    select * from a order by id;

    --[查询语句]--

    select val,count(*) from ( select id,val,row_number() over (order by id) - row_number() over (partition by val order by id) x from a ) group by val,x order by min(id);

    --[解析]--

    select id,val,row_number() over (order by id) x from a; //按id进行排序

    select id,val,row_number() over (partition by val order by id) x from a; //按val分组,分组内按id排序

    select id,val,row_number() over (order by id) - row_number() over (partition by val order by id) x from a;//id排序值 减去 val分组内id排序值 = 连续相同值的排序值

    原理:因为dense_rank() 和rownum都是连续的计数的,一个是全局计数,一个是局部分组计数,因此,两个递增频率都是1的连续相减,值应该是一样的,

    比如 全局为 1,2,3,4,5

    分组为 1,2  ;1;1,2     结果  1-1=0,2-2=0; 3-1=2;  4-1=3,5-2=3; 因此 1,2 ;4,5是连续的

    --统计一个手机连续在一个地区停留时间 created_time 定位时间 area_no 地区

    create table T_test

      MOBILE_NO          VARCHAR2(16),
      AREA_NO            VARCHAR2(10), 
      CREATED_TIME       DATE not null
    );

    写法一:
    select mobile_no, area_no, trunc(max_date - min_date), min_date, max_date
      from (select distinct mobile_no,
                            area_no,
                            min(created_time) over(partition by mobile_no, area_no, gn) min_date,
                            max(created_time) over(partition by mobile_no, area_no, gn) max_date
              from (select rownum - dense_rank() over(partition by mobile_no, area_no order by created_time) gn,
                           mobile_no,
                           area_no,
                           created_time
                      from (select a.mobile_no, a.area_no, a.created_time
                              from t_test a
                             order by mobile_no, created_time)));

    写法二:

    select mobile_no,
           area_no,
           count(*),
           min(created_time),
           max(created_time),
           max(created_time) - min(created_time)
      from (select a.mobile_no,
                   a.area_no,
                   a.created_time,
                   row_number() over(order by created_time) - row_number() over(partition by area_no order by created_time) x
              from t_test a)
     group by mobile_no, area_no, x
     order by min(created_time)

    我自己遇到的使用场景:

    需求:查询5月15日之前每一天分数最高的所有信息,但是某一天分数最高的信息可能有多条。

    以下为我的sql,可以按时间倒序排列,并且给每天分数相同的序号是一致的。

    select dense_rank() over (partition by cake.gamble_date order by cake.score desc) num,cake.*
    from t_cake cake
    where cake.cake_date<'5月15日' 
    order by cake.cake_date desc;

  • 相关阅读:
    PHP操作数据库
    ANE打包
    我的C++笔记(数据的共享与保护)
    js 正计时和倒计时
    JAVA 日期 一个时间段总共几周,每一天星期几
    mybatis 处理in
    freemarker
    正则手机验证,身份证验证
    签到
    spring定时器
  • 原文地址:https://www.cnblogs.com/yingsong/p/4793029.html
Copyright © 2020-2023  润新知