Мне нужно создать процедуру в оракуле и реализовать ниже логики
У меня есть мастер таблица с колонкой Tel_num
, Tel_num
11 цифр данных, таких как 02365785431. Теперь я должен взять первые 7 цифр tel_nums(substr( tel_nums,1,7)) и взять мин как start_num
и макс как end_num
когда числа в последовательности.
Если ниже вещи всплывают:`
023158100001
023158100002
023158100003
023158100004
023158115645
023158111546
023158111547
023158111617
023158121110
023158121111
Тогда я хочу цифры как
Start_NUM End_NUM
023158100001 023158100004
023158115645 023158111547
023158111617 023158111617
023158121110 023158121111
Эту вещь мне нужно реализовать. Может кто-нибудь помочь??
2 ответа
Нет необходимости в PL/SQL (как предлагается в комментарии). Ключевое слово - это пробелы и острова (если вы хотите найти его).
Я изменил данные выборки (поскольку они были неверны, согласно желаемому результату).
SQL> with test (tel) as
2 (select '023158100001' from dual union all
3 select '023158100002' from dual union all
4 select '023158100003' from dual union all
5 select '023158100004' from dual union all
6 select '023158111545' from dual union all
7 select '023158111546' from dual union all
8 select '023158111547' from dual union all
9 select '023158111617' from dual union all
10 select '023158121110' from dual union all
11 select '023158121111' from dual
12 ),
13 inter as
14 (select tel,
15 lag(tel) over (order by tel) lag_tel
16 from test
17 ),
18 inter_2 as
19 (select tel,
20 sum(case when nvl(tel - lag_tel, 1) = 1 then 0 else 1 end) over (order by tel) tel_group
21 from inter
22 )
23 select min(tel) min_tel,
24 max(tel) max_tel
25 from inter_2
26 group by tel_group
27 order by 1;
MIN_TEL MAX_TEL
------------ ------------
023158100001 023158100004
023158111545 023158111547
023158111617 023158111617
023158121110 023158121111
SQL>
Это будет игнорировать "первые 7 цифр" часть вопроса, потому что я не думаю, что это актуально. Я бы просто использовал разницу с номерами строк для определения смежности:
select min(tel_num), max(tel_num)
from (select mt.*,
row_number() over (order by tel_num) as seqnum
from master_table
) t
group by (cast(tel_num as decimal(11, 0)) - seqnum);
Если вас интересуют последовательности, охватывающие первые 7 цифр, просто включите их в group by
:
select min(tel_num), max(tel_num)
from (select mt.*,
row_number() over (order by tel_num) as seqnum
from master_table
) t
group by substr(tel_num, 1, 7),
(cast(tel_num as decimal(11, 0)) - seqnum);
Почему это работает? Разница между числом и последовательностью будет постоянной, когда числовые значения увеличиваются на единицу. Таким образом, когда разница постоянна, числа являются последовательными.