需求: 把连续的区间合并:反正这类似的 需求哥写的多了, 都麻木了, 这里就不说了 用图片表示
把连续的区间合并, 如上的图片 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
)