帮网友写的一个SQL(连续区间合并)

需求: 把连续的区间合并:反正这类似的 需求哥写的多了, 都麻木了, 这里就不说了 用图片表示


     把连续的区间合并, 如上的图片  7到19 连续,  也就是把 7-19 区间合并求和最后得到下面的 数据


   


  哥想直接把SQL语句 放上来得了, 不过哥不想忘记哥思考的过程, 所以哥把  思路稍微写一下 , 分许首先这个肯定用到分组,另外分组后取最值。 那如何分组呢?

 1 既然是连续 摸, 哥首先想到的是递归,  做了几遍才发现 不是的,  递归好像产生 重复数据,  另外递归的层数还不好控制。另外效率也不好, 毕竟产生重复的数据了。

 2 于是哥想到了相邻函数,    另外这个题目比较特别,  特别之处在于如何控制 相邻的数据在一组, 那就的必须先生成 分组依据列, 难点在相邻的数据标记成 一组。

    经过哥的好几次尝试 哥终于想到了 sum()  over(order by ),   这个可以实现,  于是成功解了这个 难题

 最终SQL:


 
  with t_scope as
( select  5 startno, 5 endno, 1 num from dual union all
  select  7 startno, 7 endno, 1 num from dual union all
  select  8 startno, 12 endno, 5 num from dual union all
  select  13 startno, 17 endno, 5 num from dual union all
  select  18 startno, 18 endno, 1 num from dual union all
  select  19 startno, 19 endno, 1 num from dual union all
  select  40 startno, 40 endno, 1 num from dual
  ),tab1 as(
        select t_scope.*,
      case when (lag(endno) over(order by startno)) =   startno - 1
     then  0
    else 1  end case
      from t_scope
  ),tab2 as(
     select tab1.*, sum(case) over(order by startno) de from tab1
  )
 --  select * from  tab1;
  select min(endno) min,  max(startno) max,  sum(num) sum from  tab2 group by de;
 


不过后来哥又想到一个办法,  不过也差不多,哥总会在 问题上面多想一会,  也许看到不同的风景, 或许会更美


 with t_scope as
 ( select  5 startno, 5 endno, 1 num from dual union all
   select  7 startno, 7 endno, 1 num from dual union all
   select  8 startno, 12 endno, 5 num from dual union all
   select  13 startno, 17 endno, 5 num from dual union all
   select  18 startno, 18 endno, 1 num from dual union all
   select  19 startno, 19 endno, 1 num from dual union all
   select  40 startno, 40 endno, 1 num from dual
 )
    select startno,
        endno,
        num,
        rn rw,
        last_value(rn  ignore nulls)over(order by rownum  ) rn
   from    
 (select startno,
        endno,
        num,
        (case when startno - lag(endno)over(order by rownum) = 1 then null else rownum end) rn
   from t_scope
 )







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值