Concatenation of query - oracle

How do i concatenate
SELECT abc,
abcd
FROM table
WHERE abc IN (SELECT efg
FROM table2
WHERE gfh LIKE'%a%')
in single quotes. I am having a problem while concatenating ',% and ) at the end of this query.

The best way is to use the quoting string literal technique. The syntax is q'[...]', where the "[" and "]" characters can be any of the following as long as they do not already appear in the string.
!
[ ]
{ }
( )
< >
Test case
SQL> SELECT
2 q'[select abc, abcd
3 from table
4 where abc in
5 (select efg
6 from table2
7 where gfh like '%a%')]' str_concat
8 FROM dual
9 /
STR_CONCAT
-----------------------------------------------
select abc, abcd
from table
where abc in
(select efg
from table2
where gfh like '%a%')
SQL>

Related

Extract character before space from UK postcode

In my data Postcode records are as below
1.'ABC XYZ'
2.' EFG PQR'
Requirements is to get all character before space
So for first record ,I am getting expected result if I am putting
select NVL(substr(postcode,0,instr(postcode,' ')-1), postcode)
But for second record I am getting whole postcode value . Because in second record ' '(space is at very beginning).
I tried multiple query but not getting the results .
I want single expression which handles both scenarios.
Try this:
NVL(substr(ltrim(postcode),0,instr(ltrim(postcode),' ')-1), postcode)
A simple option uses regular expressions:
Sample data:
SQL> with test (id, postcode) as
2 (select 1, 'ABC XYZ' from dual union all
3 select 2, ' EFG PQR' from dual
4 )
Query:
5 select id, postcode,
6 regexp_substr(postcode, '\w+') result
7 from test;
ID POSTCODE RESULT
---------- -------- --------
1 ABC XYZ ABC
2 EFG PQR EFG
SQL>

select matching string from another table oracle

I have a database (Oracle) Table A with some strings in one of columns, Now I want to get matching records from Table B against each column value of Table A for example,
Table A
Name
-----------
ABC
DEE
GHI
JKL
Table B
Name
-----------
ABC
DEF
GHI
JKL
MNO
PQR
Now i want that each string in Table A must be checked against Table B's column and if some string is found almost identical then it should appear against original Value as per below
Table OutPut
Name Matched
--------|----------
ABC | ABC
DEE | DEF
GHI | GHI
JKL | JKL
I have tried following query
with data as(
SELECT Name FROM TABLE_A UNION ALL
SELECT Name FROM TABLE_B
)
SELECT Name
FROM
(
SELECT t.*,utl_match.edit_distance_similarity(upper(Name),upper('DEE')) eds
FROM data t
ORDER BY eds DESC
)
WHERE rownum = 1
but problem is that using this query i can check only one record at a time and that too against a hard coded string. Is there any way to check whole column from Table A one by one against Table B and produce result in output against each string.
Not too clever (hint: performance issue, but - see if it helps. Might be OK if there aren't too many rows involved.
You need lines 21 onwards.
I set similarity to be greater than 80 - adjust it, if needed (which is very probable, as data you posted is really sample data).
SQL> WITH ta (name)
2 AS (SELECT 'ABC' FROM DUAL
3 UNION ALL
4 SELECT 'DEE' FROM DUAL
5 UNION ALL
6 SELECT 'GHI' FROM DUAL
7 UNION ALL
8 SELECT 'JKL' FROM DUAL),
9 tb (name)
10 AS (SELECT 'ABC' FROM DUAL
11 UNION ALL
12 SELECT 'DEF' FROM DUAL
13 UNION ALL
14 SELECT 'GHI' FROM DUAL
15 UNION ALL
16 SELECT 'JKL' FROM DUAL
17 UNION ALL
18 SELECT 'MNO' FROM DUAL
19 UNION ALL
20 SELECT 'PQR' FROM DUAL)
21 SELECT ta.name,
22 tb.name,
23 UTL_MATCH.jaro_winkler_similarity (ta.name, tb.name) sim
24 FROM ta, tb
25 WHERE UTL_MATCH.jaro_winkler_similarity (ta.name, tb.name) > 80
26 ;
NAM NAM SIM
--- --- ----------
ABC ABC 100
DEE DEF 82
GHI GHI 100
JKL JKL 100
SQL>

Join same table to display rows as colomn in oracle

I have a scenario where I need to take few rows from column and make it as separate column.
My present table:
Id Description
1 abc
2 abc
3 abc
4 abc
1 xyz
2 xyz
3 xyz
4 xyz
Required output:
id Desp1 Desp2
1 abc xyz
2 abc xyz
3 abc xyz
4 abc xyz
Can any one help me with this.
You could make use of the listagg function and a combination of instr and substr functions, instead of a self Join.
select id,substr(Description, 0, instr(Description, ',',1,1)-1) Desp1,
substr(Description, instr(Description, ',',1,1)+1) Desp2
from
(select id, listagg(Description,',') within group (order by Description) as
Description from sam group by id)
Note: The above query delimits the Description field by comma, and splits only into two columns as depicted in your example.

Removing duplicate data from a column

I have a table with following structure
Id Pro_id name price
----------------------------------------
1 001 ABC 200
1 002 XYZ 100
1 003 XYZ 150
2 004 PQR 100
2 005 PQR 100
2 006 LMN 200
2 007 LMN 300
2 008 DEF 150
As you can see there are some duplicate names in 'name' column.
I want to remove all the duplicate names(just need to keep first entered name and remove remaining)
So my table should look like-
Id Pro_id name price
----------------------------------------
1 001 ABC 200
1 002 XYZ 100
2 004 PQR 100
2 006 LMN 200
2 008 DEF 150
I tried following to get duplicate names-
SELECT ID, NAME, count(NAME) FROM TABLENAME
GROUP BY ID, NAME HAVING count(NAME)>1
But now I am unable to go further, stucked in how to delete the records.
any idea?
You may try below SQL (In MySQL it works)
delete t1.* from tablename t1
inner join
tablename t2 ON t1.name = t2.name
AND t1.Pro_id > t2.Pro_id
There is no "first" in SQL as the order of select is generally undefined, so the following will keep entries with the minimum value of Pro_id for duplicated names, but you are free to define a different aggregator:
DELETE FROM tablename
WHERE Pro_id NOT IN (SELECT MIN(Pro_id) FROM tablename GROUP BY name);
DELETE FROM table_name
WHERE rowid NOT IN
(
SELECT MIN(rowid)
FROM table_name
GROUP BY column1, column2, column3...
) ;
You can try something like this
delete from table1
where rowid in
(
select rid
from
(
select rowid as rid,
row_number() over (partition by name order by pro_id) as rn
from table1
)
where rn > 1
)
Havent tested it

how to match an integer with varchar containing digits separated by commas in oracle

I am facing a strange scenario where I need to match an integer with varchar containing digits separated by commas in oracle
Example:
Table t1:
id integer
key integer
Table t2
id integer,
keys varchar2
T1 values are:
1,111
2,201
3,301
T2 values are:
1, "111,301"
2, "111,201"
3, "201,301"
PROBLEM: Is there any way I can match or regular_expression match with key of T1 with keys of T2?
you can do a regular join without regex for this:
select *
from t1
inner join t2
on ','||t2.keys||',' like '%,'||to_char(t1.key)||',%';
eg:
SQL> create table t1(id, key)
2 as
3 select 1, 111 from dual union all
4 select 2, 201 from dual union all
5 select 3, 301 from dual;
Table created.
SQL> create table t2(id, keys)
2 as
3 select 1, '111,301' from dual union all
4 select 2, '111,201' from dual union all
5 select 3, '201,301' from dual;
Table created.
SQL> select *
2 from t1
3 inner join t2
4 on ','||t2.keys||',' like '%,'||to_char(t1.key)||',%';
ID KEY ID KEYS
---------- ---------- ---------- -------
1 111 1 111,301
1 111 2 111,201
2 201 2 111,201
2 201 3 201,301
3 301 1 111,301
3 301 3 201,301
6 rows selected.
It's not regex, just concatenation. For example lets say we wanted to compare
KEY KEYS
111 111,301
we could say
where keys like '%'||key||'%'
i.e. expanded, this is
where '111,301' like '%111%'
which matches fine. But I added some commas there too. ie I did this:
where ',111,301,' like '%,111,%'
Why? imagine instead you had this data:
KEY KEYS
111 1111,301
If we did the simple join:
where '1111,301' like '%111%'
it would incorrectly match. By injecting leading and trailing commas on both sides:
where ',1111,301,' like '%,111,%'
is no longer erroneously matches, as ,1111, isn't like ,111,.

Resources