SELECT STATMENT IN OR LIKE OR REGEXP - sql

I have a table new_table
ID DESCRIPTION
1 abdad jadjnd kandkadn 01/19-P-154-37
2 jscbsjc jscnscj 01/19-H-443-38 sbjcj sjcnjscn
3 scjbcs sc, scnsc 01/19-P-16-39 sjcbnjcs
4 scbcsjc 01/19-K-139-40 hcbchsb
AND LISTS
01/19-P-154-37
01/19-H-443-38
01/19-K-139-40
I want to
select * from new_table where descriptin in (
01/19-P-154-37
01/19-H-443-38
01/19-P-16-39
01/19-K-139-40
)
OR LIKE I don't now please help

I guess you want something like this (join with like operator):
with new_table (ID, DESCRIPTION) as (
select 1 ,'abdad jadjnd kandkadn 01/19-P-154-37' from dual union all
select 2 ,'jscbsjc jscnscj 01/19-H-443-38 sbjcj sjcnjscn' from dual union all
select 3 ,'scjbcs sc, scnsc 01/19-P-16-39 sjcbnjcs' from dual union all
select 4 ,'scbcsjc 01/19-K-139-40 hcbchsb' from dual
) ,
LISTS(val) as(
select '01/19-P-154-37' from dual union all
select '01/19-H-443-38' from dual union all
select '01/19-K-139-40' from dual
)
-- Below is actual query:
select new_table.* from new_table
inner join LISTS
on new_table.DESCRIPTION like '%'||LISTS.val||'%'

Related

Returning result in Json and table type SQL Oracle

I have a table in which with repeating id.
The goal is (to make a select) to get all the results of the repeating id to pour against each id in Json format as id it's not in Json
id,yyyy,name
1,2010,a
1,2011,b
2,2010,a
3,2010,c
3,2011,a
4,2011,v
Desired result
id, column(json)
1 {"2010":"a","2011","b"}
2 {"2010":"a","2010":"c"}
3 {"2010":"c","2011":"a"}
4 {"2011":"v"}
with data(id, y, name) as (
select 1,2010,'a' from dual union all
select 1,2011,'b' from dual union all
select 2,2010,'a' from dual union all
select 3,2010,'c' from dual union all
select 3,2011,'a' from dual union all
select 4,2011,'v' from dual -- union all
)
select id, json_objectagg(
key to_char(y) value name) as obj
from data
group by id
;
1 {"2010":"a","2011":"b"}
2 {"2010":"a"}
3 {"2010":"c","2011":"a"}
4 {"2011":"v"}

How to filter data from 2 different tables in SQL but the other table has few strings to ignore?

For example:
One table has account name such as Apple, Google, Facebook.
Other table has account name as 2-apple,3-google,4-facebook.
I need to combine those 2 tables based on account name but want the query to ignore the first 2 string values from the other table = bolded values(2-apple, 3-google, 4-facebook).
In Oracle (as you tagged it), you'd use SUBSTR function:
select whatever
from t1 join t2 on t1.name = substr(t2.name, 3)
as it returns what you wanted, e.g.
SQL> select substr('2-apple', 3) result from dual;
RESUL
-----
apple
SQL>
Keeping in mind lowercase to avoid problems with the comparison
with x as (
select 'Google' as mark from dual union all
select 'Facebook' as mark from dual
),
y as (
select '2-apple' as other from dual union all
select '3-google' as other from dual union all
select '4-facebook' as other from dual
)
select x.mark, y.other
from x inner join y
on ( lower(x.mark) = lower(substr(y.other,3)) );
Result
SQL> with x as (
select 'Google' as mark from dual union all
select 'Facebook' as mark from dual
),
y as (
select '2-apple' as other from dual union all
select '3-google' as other from dual union all
select '4-facebook' as other from dual
)
select x.mark, y.other
from x inner join y
on ( lower(x.mark) = lower(substr(y.other,3)) );
MARK OTHER
-------- ----------
Google 3-google
Facebook 4-facebook

Set flag column based on a regular expression

I have developed the following query but it does not work as expected:
WITH TABLE1 AS
(
SELECT 613414473 as ID, 1706014200964 as P_NUM, 119539 as d_id, 'F20.0' AS CODE FROM DUAL UNION ALL
SELECT 613414473 as ID, 1706014200964 as P_NUM, 119539 as d_id, 'F22.0' AS CODE FROM DUAL UNION ALL
SELECT 613415801 as ID, 1707045167741 as P_NUM, 115182 as d_id, 'A94.0' AS CODE FROM DUAL UNION ALL
SELECT 613415801 as ID, 1707045167741 as P_NUM, 115182 as d_id, NULL AS CODE FROM DUAL UNION ALL
SELECT 613417084 as ID, 1702038456441 as P_NUM, 6541 as d_id, 'E79' AS CODE FROM DUAL UNION ALL
SELECT 613417084 as ID, 1702038456421 as P_NUM, 6541 as d_id, 'I10' AS CODE FROM DUAL UNION ALL
SELECT 613418372 as ID, 1706226211517 as P_NUM, 25727 as d_id, 'F32.9' AS CODE FROM DUAL )
SELECT T1.*
, CASE when regexp_like( CODE, 'C0[5-9]|' ||
'A0[0-9]|A1[0-9]|A2[0-9]|A3[0-9]|A4[0-9]|A5[0-9]|A6[0-9]|A7[0-9]|A8[0-9]|A9[0-7]|' )
THEN 1
ELSE 0 END AS FOUND_CODE
FROM TABLE1 T1;
I want codes which are like C0[5-9]% or A0[0-97] to be flagged with value 1, and then for the same p_num, if at least one code was found to set all the flags for that p_num to 1.
Example output of the above:
| 613414473|1706014200964|119539|F20.0|0|
| 613414473|1706014200964|119539|F22.0|0|
| 613415801|1707045167741|115182|A94.0|1|
| 613415801|1707045167741|115182|NULL |1|
| 613417084|1702038456441|6541 |E79 |0|
| 613417084|1702038456421|6541 |I10 |0|
| 613418372|1706226211517|25727 |F32.9|0|
How can I modify my query to get that output? And is there a better regular expression I can use?
Based on your description, the regular expression pattern should be
'^(C0[5-9]|A[0-8][0-9]|A9[0-7])'
The ^ anchors to the start of the value, and the parentheses allow any of the pipe-separated patterns to match; and the patterns are simplified, as A00 to A89 can be handles in one go.
That flags the same single row as your original query. The next stage is to move that into a subquery, and then use an analytic function partitioned by the p_num which you want to be common:
max(found_code) over (partition by p_num)
So together that becomes (with additional rows to match a different rule):
with table1 (id, p_num, d_id, code) as
(
select 613414470, 1706014200960, 119530, 'D99' from dual union all
select 613414471, 1706014200960, 119531, 'C05' from dual union all
--
select 613414473, 1706014200964, 119539, 'F20.0' from dual union all
select 613414473, 1706014200964, 119539, 'F22.0' from dual union all
select 613415801, 1707045167741, 115182, 'A94.0' from dual union all
select 613415801, 1707045167741, 115182, null from dual union all
select 613417084, 1702038456441, 6541 , 'E79' from dual union all
select 613417084, 1702038456421, 6541 , 'I10' from dual union all
select 613418372, 1706226211517, 25727 , 'F32.9' from dual
)
select id, p_num, d_id, code, max(found_code) over (partition by p_num) as found_code
from (
select t1.*
, case when regexp_like( code, '^(C0[5-9]|A[0-8][0-9]|A9[0-7])' )
then 1
else 0
end as found_code
from table1 t1
);
ID P_NUM D_ID CODE FOUND_CODE
------------- ------------- ------------- ----- -------------
613414470 1706014200960 119530 D99 1
613414471 1706014200960 119531 C05 1
613414473 1706014200964 119539 F20.0 0
613414473 1706014200964 119539 F22.0 0
613415801 1707045167741 115182 A94.0 1
613415801 1707045167741 115182 1
613417084 1702038456441 6541 E79 0
613417084 1702038456421 6541 I10 0
613418372 1706226211517 25727 F32.9 0

ROUND SQL WITH 3 DECIMAL AFTER PLACES

I want to do this please
select round(9.100000, 3) from dual
Result = 9.100
select round(12679.1000001, 3) from dual
Result = 12679.100
Thanks
You can do it with to_char method :
select to_char(9.100000, '999.999') from dual
select to_char(12679.1000001, '99999.999') from dual
Example with a table rather than with constant values:
with temp as (
select 9.100000 as num from dual
union
select 12679.1000001 as num from dual
union
select -20.2356 as num from dual
)
select to_char(num,'99999.999') from temp

How to convert String in SQL (ORACLE)

I try to select from table_1 where ITEM_FIELD_A is not in ITEM_FIELD_B. The Item_FIELD_B value are look as below. I was expecting no COVER_TAPE & SHIPPING_REELS will be selected. But unfortunately, it's not working.
The sql I used to select the table
select * from table_1 where MST.ITEM_FIELD_A not in ITEM_FIELD_B
Question:
In Oracle, is there any function to decode the string. so that the above select statement will not return COVER_TAPE and SHIPPING_REELS??
The IN operator would be used when you wish to compare (or negate) one item in a list such as
WHERE ITEM_FIELD_A NOT IN ('COVER_TAPE', 'SHIPPING_REELS', '')
What you want is the LIKE operator:
WHERE ITEM_FIELD_B NOT LIKE '%' || ITEM_FIELD_A || '%'
Apologies if I got the wildcard wrong, been a while since I last touched Oracle.
Check out below Query:
WITH TAB1 AS
( SELECT 'COVER_TAPE' ITEM_A FROM DUAL
UNION
SELECT 'CARRIER_TAPE' ITEM_A FROM DUAL
UNION
SELECT 'SHIPPING_REELS' ITEM_A FROM DUAL
),
TAB2 AS
(
SELECT 'COVER_TAPE,SHIPPING_REELS' ITEM_B FROM DUAL
)
SELECT ITEM_A, ITEM_B FROM TAB1, TAB2 WHERE INSTR(ITEM_B, ITEM_A) <=0
INSTR will return >0 if same sequence of characters is available.
SQL> with t(x , y) as
2 (
3 select 'A', q'[('A','B','C')]' from dual union all
4 select 'R', q'[('A','B','C','D')]' from dual union all
5 select 'C', q'[('A', 'C','D')]' from dual
6 )
7 select x, y
8 from t where y not like q'[%']'||x||q'['%]'
9 /
X Y
---------- --------------------------------------------------
R ('A','B','C','D')