Remove semicolon from the end or individually - sql

I am getting an output of one table as
FILE_NUM SNO
Read;write;Listen; 1
Listen; 2
; 3
Write;READ; 4
I want to tweak the above column such as ; at the end is removed and if only ";" is given it should be removed like
FILE_NUM SNO
Read;write;Listen 1
Listen 2
3
Write;READ 4

Use RTRIM():
SELECT RTRIM(FILE_NUM, ';') AS FILE_NUM, SNO
FROM yourTable
ORDER BY SNO;
You could also use REGEXP_REPLACE here:
SELECT REGEXP_REPLACE(FILE_NUM, ';$', '') AS FILE_NUM, SNO
FROM yourTable
ORDER BY SNO;

Right-trim it.
SQL> with test (file_num) as
2 (select 'read;write;listen;' from dual union all
3 select 'listen;' from dual union all
4 select ';' from dual union all
5 select 'write;read;' from dual
6 )
7 select file_num,
8 rtrim(file_num, ';') result
9 from test;
FILE_NUM RESULT
------------------ ------------------
read;write;listen; read;write;listen
listen; listen
;
write;read; write;read
SQL>

Related

Count occurences of values in table, when I treat one value as occurence of all other values

I have a table with one column (just to simplify the problem) with values 0-23 or *.
I want to count occurrences of each value 0-23, but treat * as occurrence of all other values
for example:
column_name
-------------
3
4
5
6
7
*
4
4
3
*
I want to get something like that:
column_name | count
--------------------
1 | 2
2 | 2
3 | 4
4 | 5
5 | 3
6 | 3
7 | 3
.....
I tried experimenting with different count and "group by" methods, but always getting very strange results. Basically the main problem here is to how count rows when I need to have one value in all other groups.
You could use analytic function that counts values where * is replaced by actual value between 0 and 23:
SELECT DISTINCT n.RN "COL_1", Count(REPLACE(t.COL_1, '*', n.RN)) OVER(Partition By n.RN) "CNT"
FROM tbl t
INNER JOIN ( Select To_Char(LEVEL - 1) "RN" From Dual Connect By LEVEL <=24 ) n ON(n.RN = REPLACE(t.COL_1, '*', n.RN))
WHERE n.RN IN(SELECT COL_1 FROM tbl)
ORDER BY To_Number(n.RN)
which with your sample data:
WITH
tbl (COL_1) AS
(
Select '3' From Dual Union All
Select '4' From Dual Union All
Select '5' From Dual Union All
Select '6' From Dual Union All
Select '7' From Dual Union All
Select '*' From Dual Union All
Select '4' From Dual Union All
Select '4' From Dual Union All
Select '3' From Dual Union All
Select '*' From Dual Union All
Select '3' From Dual
)
... results as:
COL_1 CNT
---------------------------------------- ----------
3 5
4 5
5 3
6 3
7 3
... and if you exclude the Where clause you will get all the rows (0 - 23) with number of occurances counted by REPLACE of * with any of the numbers
COL_1 CNT
---------------------------------------- ----------
0 2
1 2
2 2
3 5
4 5
5 3
6 3
7 3
8 2
9 2
10 2
11 2
12 2
13 2
14 2
15 2
16 2
17 2
18 2
19 2
20 2
21 2
22 2
23 2
You can do it using successive WITH's :
First one to calculate number of occurrence of *.
And the second is to calculate number of occurrence of each number.
with cte as (
select count(1) as c
from mytable
where column_name = '*'
),
cte2 as (
select column_name, count(1) as c
from mytable, cte
group by column_name
)
select column_name, cte.c + cte2.c
from cte2, cte;
You can with nested statements too,
SELECT ID,(count_ + (
SELECT COUNT(ID) FROM sql_test_a
WHERE ID = '*')) as count_
FROM (
SELECT ID,COUNT(ID) as count_
FROM sql_test_a WHERE ID != '*' GROUP BY ID);

How to search for a name in where Oracle with string and number character

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>

How do I extract the first 3 consonates from a string field SQL?

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.

Always show a value highst when sorting

I Oracle, I have a table with following values
1
2
4
10
I always want 2 to show up highest following by all other values in DESCending order, as follows :
2
10
4
1
You can order by a value you build with a case; for example:
with tab(col) as (
select 1 from dual union all
select 2 from dual union all
select 4 from dual union all
select 10 from dual
)
select col
from tab
order by case when col = 2 then 1 else 2 end asc,
col desc
gives:
COL
----------
2
10
4
1
try like below if column is not null
with tab(col) as (
select 1 from dual union all
select 2 from dual union all
select 4 from dual union all
select 10 from dual
)
select col
from tab
ORDER BY NULLIF(col, 2) desc NULLS FIRST
output
COL
2
10
4
1
demo link

Selecting rows where column having number as substring

I have to write a query to fetch all the rows with a column containing numbers as substring
Data
------
abc123
defgh
wz127bdn
Now my desired result is
Result
-----
abc123
wz127bdn
I wrote the query like
SELECT data
FROM table
WHERE data like '%[0-9]%'
But this is not fetching the result.
You need a REGEXP_LIKE:
SQL> with test(data) as (
2 select 'abc123' from dual union all
3 select 'defgh' from dual union all
4 select 'wz127bdn' from dual union all
5 select '[0-9]' from dual
6 )
7 select *
8 from test
9 where regexp_like(data, '[0-9]')
10 ;
DATA
--------
abc123
wz127bdn
[0-9]
LIKE will not interpret '[0-9]' as "look for a digit", but exactly as you write it, thus searching for the string '[0-9]':
SQL> with test(data) as (
2 select 'abc123' from dual union all
3 select 'defgh' from dual union all
4 select 'wz127bdn' from dual union all
5 select '[0-9]' from dual
6 )
7 select *
8 from test
9 where data like '%[0-9]%' ;
DATA
--------
[0-9]
Use regexp_like() in Oracle:
SELECT data
FROM table
WHERE regexp_like(data, '[0-9]');
Note that the wildcards are not necessary, because regular expressions match anywhere in the string. If you like, you can do:
WHERE regexp_like(data, '.*[0-9].*');