I have a string column that has the values like below
Column A
(9167)
1042
21463
9979
(26351)
I need the output like below -
Output
-9167
1042
21463
9979
-26351
I need to trim the brackets and replace that with '-' Symbol by using update statement. Is there a way we can do it with a query?
How about this:
with demo (column_a) as
( select '(9167)' from dual union all
select '1042' from dual union all
select '21463' from dual union all
select '9979' from dual union all
select '(26351)' from dual )
select column_a
, case
when trim(column_a) like '(%)' then
to_number(regexp_replace(column_a,'[()]')) * -1
else to_number(column_a)
end as result
from demo;
COLUMN_A RESULT
-------- ----------
(9167) -9167
1042 1042
21463 21463
9979 9979
(26351) -26351
Use Translate 'from characters', 'to characters'
As the user guide states, "TRANSLATE lets you make several single-character, one-to-one substitutions in one operation."
One just maps the replacement characters as follows:
from: ()
to: -
where the 1st from character ( is mapped to the 1st to character -
where the 2nd from character ) is mapped to the 2nd to character, which doesn't exist so is null
SCOTT#db>WITH tst AS (
2 SELECT
3 '(9167)' val FROM
4 dual
5 union all
6 select
7 '1042' val FROM
8 dual
9 union all
10 select
11 '21463' val FROM
12 dual
13 union all
14 select
15 '9979' val FROM
16 dual
17 union all
18 select
19 '(26351)' val
20 FROM
21 dual
22 ) SELECT
23 translate(t.val,'()','-')
24 FROM
25 tst t;
TRANSLA
-------
-9167
1042
21463
9979
-26351
Related
I need to find records in Oracle that have only such record like 'string|number|number|number|number|number' for example - 'A12345'
select * from base where column_x like 'string|number|number|number|number|number'
That's a letter followed by 5 digits:
SQL> with test (col) as
2 (select 'A12345' from dual union all
3 select 'B123CD' from dual union all
4 select '123ABC' from dual
5 )
6 select *
7 from test
8 where regexp_like(col, '^[[:alpha:]]{1}[[:digit:]]{5}$');
COL
------
A12345
SQL>
I have a column field in the below situation:
LENGTH(FIELD_NAME)
COUNT(*)
6
1271
7
81
5
33
3
125
1
12
I want to normalize this field so that all rows contain 6 digits. The requirements is to go from right to left and add leading zeros if necessary.
The solution I came up with is as follows:
CASE
WHEN LENGTH(FIELD_NAME) < 6 THEN LPAD(FIELD_NAME, 6, '0')
WHEN LENGTH(FIELD_NAME) > 6 THEN SUBSTR(FIELD_NAME, -6)
ELSE FIELD_NAME
END
Is there a more efficient (better) way to achieve the same result?
You can prepend six zeroes and then take the sub-string of the last 6 characters:
SELECT SUBSTR('000000' || value, -6) as short_field_name
FROM table_name;
Which, for the sample data:
CREATE TABLE table_name (value) AS
SELECT '123' FROM DUAL UNION ALL
SELECT '1234' FROM DUAL UNION ALL
SELECT '12345' FROM DUAL UNION ALL
SELECT '123456' FROM DUAL UNION ALL
SELECT '1234567' FROM DUAL UNION ALL
SELECT '12345678' FROM DUAL UNION ALL
SELECT '123456789' FROM DUAL;
Outputs:
SHORT_FIELD_NAME
000123
001234
012345
123456
234567
345678
456789
db<>fiddle here
how can I extract from a field in records that contain names only the first 3 consonants and if a name does not have 3 consonants it adds the first vowel of the name?
For example, if I had the following record in the People table:
Field:Name
VALUE:Richard result=> RCH
FIELD:Name
VALUE:Paul result=> PLA
Here's one option; read comments within code.
Sample data:
SQL> with test (name) as
2 (select 'Richard' from dual union all
3 select 'Paul' from dual
4 ),
Query begins here:
5 temp as
6 -- val1 - consonants; val2 - vowels
7 (select
8 name,
9 translate(upper(name), '#AEIOU', '#') val1,
10 translate(upper(name), '#BCDFGHJKLMNPQRSTWXYZ', '#') val2
11 from test
12 )
13 -- finally: if there are enough consonants (val1's length is >= 3), return the first 3
14 -- letters (that's WHEN).
15 -- Otherwise, add as many vowels as necessary (that's what ELSE does)
16 select name,
17 case when length(val1) >= 3 then substr(val1, 1, 3)
18 else val1 || substr(val2, 1, 3 - length(val1))
19 end result
20 from temp;
NAME RESULT
------- --------------
Richard RCH
Paul PLA
SQL>
Just for fun using regexp:
select
name
,substr(
regexp_replace(
upper(name)
,'^([AEIOU]*)([^AEIOU]*)([AEIOU]*)([^AEIOU]*)([AEIOU]*)([^AEIOU]*).*'
,'\2\4\6\1\3\5'
),1,3) as result
from test;
([AEIOU]*) - is a group of vowels, 0 or more characters
([^AEIOU]*) - is a group of not-vowels (or consonants in this case), 0 or more characters
so this regexp looks for a pattern (vowels1)(consonants1)(vowels2)(consonants2)(vowels3)(consonants3) and reorders it to (consonants1)(consonants2)(consonants3)(vowels1)(vowels2)(vowels3)
then we just take first 3 characters from the reordered string
Full test case:
with test (name) as
(select 'Richard' from dual union all
select 'Paul' from dual union all
select 'Annete' from dual union all
select 'Anny' from dual union all
select 'Aiua' from dual union all
select 'Isaiah' from dual union all
select 'Sue' from dual
)
select
name
,substr(
regexp_replace(
upper(name)
,'^([AEIOU]*)([^AEIOU]*)([AEIOU]*)([^AEIOU]*)([AEIOU]*)([^AEIOU]*).*'
,'\2\4\6\1\3\5'
),1,3) as result
from test;
NAME RESULT
------- ------------
Richard RCH
Paul PLA
Annete NNT
Anny NNY
Aiua AIU
Isaiah SHI
Sue SUE
7 rows selected.
I would like to create a query where I select all records which may contain letters, digits and special characters from group of 3 special characters: / " ,
I've tried '[0-9a-zA-Z(\-\/\")]' but something like 'a+' works
Try this regex:
[0-9a-zA-Z/",]+
Something like this?
SQL> with test (col) as
2 (-- valid values
3 select 'Little12' from dual union all
4 select 'Foot/15' from dual union all
5 select '"London",UK' from dual union all
6 -- invalid values
7 select '25+ miles' from dual union all
8 select 'me#gmail.com' from dual
9 )
10 select col
11 from test
12 where regexp_like(col, '^[a-zA-Z0-9/",]*$');
COL
------------
Little12
Foot/15
"London",UK
SQL>
Input is:
Section1
Section2
Section3
Section10
Section11
Section1A
Section1B
Section12
Section11A
Section11B
And I want output like:
Section1
Section1A
Section1B
Section2
Section3
Section10
Section11
Section11A
Section11B
Section12
I tried query :
select section_name
from sections
order by length(section_name),section_name
Assuming that the structure of your strings is fixed, as in your example, this could be a way:
SQL> select x,
2 to_number(regexp_substr(x, '[0-9]+')) numericPart,
3 regexp_substr(x, '([0-9]+)([A-Z])', 1, 1, '', 2) optionalChar
4 from (
5 select 'Section1' x from dual union all
6 select 'Section2' from dual union all
7 select 'Section3' from dual union all
8 select 'Section10' from dual union all
9 select 'Section11' from dual union all
10 select 'Section1A' from dual union all
11 select 'Section1B' from dual union all
12 select 'Section12' from dual union all
13 select 'Section11A' from dual union all
14 select 'Section11B' from dual
15 )
16 order by numericPart,
17 optionalChar nulls first
18 ;
X NUMERICPART OPTIONALCHAR
---------- ----------- ----------------------------------------
Section1 1
Section1A 1 A
Section1B 1 B
Section2 2
Section3 3
Section10 10
Section11 11
Section11A 11 A
Section11B 11 B
Section12 12
Here you first order by the numeric part, treating it as number, and then consider the (optional) character after the number.