Home > Software engineering >  Find if number repeats more of 4 times - ORACLE SQL
Find if number repeats more of 4 times - ORACLE SQL

Time:10-26

I have a list of telephone number (in ORACLE SQL), et i have to check in this list, if a number contains 4 times a number consecutively. In that case, i have to set the value to null. Exemple:

TEL STATUS
012345678 OK
021444458 NULL
339547214 OK
111105874 NULL

How can i check this? Thank you

CodePudding user response:

Here's how I understood it (read comments within code):

SQL> with test (tel) as
  2    -- sample data
  3    (select '012345678' from dual union all
  4     select '021444458' from dual union all
  5     select '339547214' from dual union all
  6     select '111105874' from dual
  7    ),

  8  cons (dig) as
  9    -- generated consecutive digits, 0000, 1111, ..., 9999
 10    (select lpad(level - 1, 4, level - 1)
 11     from dual
 12     connect by level <= 10
 13    ),
 14  temp as
 15    -- check whether any TEL number constains consecutive digits
 16    (select t.tel,
 17       c.dig,
 18       case when instr(t.tel, c.dig) > 0 then 'NOK'
 19            else 'OK'
 20       end as status
 21     from test t cross join cons c
 22    )
 23  -- finally, two groups: those that are OK (don't contain consecutive digits) and ...
 24  select a.tel, 'OK'
 25  from test a
 26  where not exists (select null from temp b
 27                    where b.tel = a.tel
 28                      and b.status = 'NOK'
 29                   )
 30  union all
 31  -- ... those that contain 4 consecutive digits
 32  select a.tel, 'NULL'
 33  from test a
 34  where     exists (select null from temp b
 35                    where b.tel = a.tel
 36                      and b.status = 'NOK'
 37                   )
 38  order by tel;

TEL       'OK'
--------- ----
012345678 OK
021444458 NULL
111105874 NULL
339547214 OK

SQL>

[EDIT: converting to UPDATE]

Data before:

SQL> SELECT * FROM test;

TEL       STATUS
--------- ----------
012345678
021444458
339547214
111105874

Update:

SQL> UPDATE test t
  2     SET t.status =
  3            (WITH
  4                cons (dig)
  5                AS
  6                   -- generated consecutive digits, 0000, 1111, ..., 9999
  7                   (    SELECT LPAD (LEVEL - 1, 4, LEVEL - 1)
  8                          FROM DUAL
  9                    CONNECT BY LEVEL <= 10),
 10                temp
 11                AS
 12                   -- check whether any TEL number constains consecutive digits
 13                   (SELECT t.tel,
 14                           c.dig,
 15                           CASE
 16                              WHEN INSTR (t.tel, c.dig) > 0 THEN 'NOK'
 17                              ELSE 'OK'
 18                           END AS status
 19                      FROM test t CROSS JOIN cons c),
 20                -- finally, two groups: those that are OK (don't contain consecutive digits) and ...
 21                temp2
 22                AS
 23                   (SELECT a.tel, 'OK' status
 24                      FROM test a
 25                     WHERE NOT EXISTS
 26                              (SELECT NULL
 27                                 FROM temp b
 28                                WHERE     b.tel = a.tel
 29                                      AND b.status = 'NOK')
 30                    UNION ALL
 31                    -- ... those that contain 4 consecutive digits
 32                    SELECT a.tel, 'NULL' status
 33                      FROM test a
 34                     WHERE EXISTS
 35                              (SELECT NULL
 36                                 FROM temp b
 37                                WHERE     b.tel = a.tel
 38                                      AND b.status = 'NOK'))
 39             SELECT t2.status
 40               FROM temp2 t2
 41              WHERE t2.tel = t.tel);

4 rows updated.

Data after:

SQL> SELECT * FROM test;

TEL       STATUS
--------- ----------
012345678 OK
021444458 NULL
339547214 OK
111105874 NULL

SQL>

CodePudding user response:

As another solution, you could use regexp_like to get the job done. The regex expression (\d)(\1){3,} will match any digit that repeats consecutively at least four times.

with t (TEL) as (
select '012345678' from dual union all
select '021444458' from dual union all
select '339547214' from dual union all
select '111105874' from dual
)
select TEL, case when not regexp_like(TEL, '(\d)(\1){3,}') then 'OK' end STATUS
from t ;

Then, update would be like this

UPDATE test t
  SET t.status = case when not regexp_like(TEL, '(\d)(\1){3,}') then 'OK' else null end
;
  • Related