I am trying to find out all the tables where table names consist of numbers less than a fixed number 16284961 at the end preceded by an underscore for example LOG_16282961.
Sample User_segments table:
Segment_name Bytes
---------------------------------------
LOG_16282961 34
BAL1_16282961 78
BIN$xIDte/qXAFbgU4IeBEeQpw==$0 12
EXCH_16282961 28
C$_0LOG_16282961 17
LOG_16283961 89
BAL1_16283961 10
BIN$xIDte/qWAFbgU4IeBEeQpw==$0 19
EXCH_16283961 90
C$_0LOG_16283961 45
LOG_16284961 21
BAL1_16284961 81
BIN$w1RLAvSeAWjgU4IeBEe2Mw==$0 33
EXCH_16284961 67
C$_0LOG_16284961 39
Expected Output:
Segment_name Bytes
----------------------
LOG_16282961 34
BAL1_16282961 78
EXCH_16282961 28
C$_0LOG_16282961 17
LOG_16283961 89
BAL1_16283961 10
EXCH_16283961 90
C$_0LOG_16283961 45
..
..
Query:
SELECT segment_name, bytes/1024/1024 AS "SIZE in MB" FROM user_segments WHERE segment_type='TABLE' AND to_number(regexp_substr(segment_name, '[0-9]+')) < 16284961;
Using above query, although I am getting my result but additionally it also includes following tables which are not required in my output:
BIN$xIDte/qXAFbgU4IeBEeQpw==$0 12
BIN$xIDte/qWAFbgU4IeBEeQpw==$0 19
BIN$w1RLAvSeAWjgU4IeBEe2Mw==$0 33
Can you please help fix my query to get the desired output? Thanks.
Advertisement
Answer
Here’s one way – using regexp_substr
to isolate one or more consecutive digits at the end of the input string, only if immediately preceded by underscore. (If the string does not have that structure, regexp_substr
returns null
and the filter condition becomes null < [something]
, which is never true
.)
Create mock-up table for testing:
create table test_data (segment_name, bytes) as
select 'LOG_16282961' , 34 from dual union all
select 'BAL1_16282961' , 78 from dual union all
select 'BIN$xIDte/qXAFbgU4IeBEeQpw==$0', 12 from dual union all
select 'EXCH_16282961' , 28 from dual union all
select 'C$_0LOG_16282961' , 17 from dual union all
select 'LOG_16283961' , 89 from dual union all
select 'BAL1_16283961' , 10 from dual union all
select 'BIN$xIDte/qWAFbgU4IeBEeQpw==$0', 19 from dual union all
select 'EXCH_16283961' , 90 from dual union all
select 'C$_0LOG_16283961' , 45 from dual union all
select 'LOG_16284961' , 21 from dual union all
select 'BAL1_16284961' , 81 from dual union all
select 'BIN$w1RLAvSeAWjgU4IeBEe2Mw==$0', 33 from dual union all
select 'EXCH_16284961' , 67 from dual union all
select 'C$_0LOG_16284961' , 39 from dual
;
Query and output:
select *
from test_data
where to_number(regexp_substr(segment_name, '_(d+)$', 1, 1, null, 1))
< 16284961
;
SEGMENT_NAME BYTES
------------------------------ ----------
LOG_16282961 34
BAL1_16282961 78
EXCH_16282961 28
C$_0LOG_16282961 17
LOG_16283961 89
BAL1_16283961 10
EXCH_16283961 90
C$_0LOG_16283961 45