compare "string1" with comma separated "string2" without splitting - oracle

I need to match string1 with comma seperated values in string2 without splitting string2. For example, given:
String1: 'abc'
String2: '123,fgh,abc,tg,sd'
string1 should be compared with string2 and should return true as 'abc' is part of string2. Is there any way to do it??
Note. INSTR() doesn't solve this. If string2 is : '123,efabcde,34' it will return true but I need to compare only with comma separated values ("whole words")

Hope this may help you
INSTR2('123,fgh,abc,tg,sd.com', 'abc')

You could use REGEXP_LIKE function
Here is an example for your case:
with mydata as (
select '123,fgh,abc,tg,sd' d from dual
union
select '123,fgh,abcd,tg,sd' d from dual
union
select 'abc,123,fgh,abcd,tg,sd' d from dual
union
select 'abcd,xabc' d from dual
union
select 'abc' d from dual
)
select d,
case
when REGEXP_LIKE(d,',abc,|^abc,|,abc$|^abc$')
then 'Y'
else 'N'
end as res_y_n
from mydata
and the results:
123,fgh,abc,tg,sd Y
123,fgh,abcd,tg,sd N
abc Y
abc,123,fgh,abcd,tg,sd Y
abcd,xabc N

If str is the string containing the comma separated list of strings then
str is equal to abc
str is equal to abc,...
str is equal to ...,abc
str is equal to ...,abc,...
... is an arbitrary string.
You can use string functions, string operators or regular expression to check this. Using string operators you get
(str = 'abc') or
(str like 'abc,%') or
(str like '%,abc') or
(str like '%,abc,%')
if the string you search for (abc in this example) contains the characters % or _ then you have to quote them because they have a special meaning in LIKE expressions. You also have to quote the quote character. So if you search for 10% you use
(str = '10%') or
(str like '10\%,%') escape '\' or
(str like '%,10\%') escape '\' or
(str like '%,10\%,%') escape '\'
A regular expression solution with REGEXP_LIKE looks like more compact then a solution using LIKE or string functions but there are more special characters you have to quote.
If you use string functions (using INSTR, SUBSTR, LENGTH) then there are no special characters but the solution is less compact than this solution using LIKE.

Related

how to trim leading zero in oracle sql from concatenation text (text:number-number-number

how to trim leading zero in oracle sql from concatenation text
(text:number-number-number)
example(word:number-number-number) word can have text or double zero
but always has char before it after word, max digits separated by '-'
all time max 3 digits i want to keep zeros in first part. and after
that if remove leading 0 in sequence but keep it if it's only one 0
MachineAbc00:1-0-03 = MachineAbc00:1-0-3
MachineAbc00:1-001-02 = MachineAbc00:1-1-2
tried many combination, not successful , like
REGEXP_REPLACE ('MachineO00:1-0-03*', '0+(?!$)', '-')
REGEXP_REPLACE ('MTROPQFMO00:1-0-03*', '(-0){1,}', '-')
If all the input strings are in the exact format you said they are, then something like this should work:
with
sample_strings (str) as (
select 'MachineAbc00:1-0-03' from dual union all
select 'MachineAbc00:1-001-02' from dual union all
select 'MachineZzzyx:200-020-002' from dual union all
select 'machineCX032:0-000-0' from dual
)
select str as old_str,
regexp_replace(str, '([:-])0*(\d+)', '\1\2') as new_str
from sample_strings
;
OLD_STR NEW_STR
------------------------ ------------------------
MachineAbc00:1-0-03 MachineAbc00:1-0-3
MachineAbc00:1-001-02 MachineAbc00:1-1-2
MachineZzzyx:200-020-002 MachineZzzyx:200-20-2
machineCX032:0-000-0 machineCX032:0-0-0
The regular expression function finds any occurrence of (colon or dash) followed by (zero or more 0 characters/digits) followed by at least one more digit. The "zero or more 0 digits" is maximal with the property that there must be at least one more digit AFTER that match (even if that extra digit hapens to be a zero - see my last test string, which I added precisely in order to test that this works correctly). The function replaces each such occurrence with the first and third fragments, removing the middle one (the zeros you must remove from your string). The references \1 and \2 refer to the first and the second parenthesized sub-expressions - the punctuation mark (colon or dash) and, respectively, the final digits (excluding the leading zeros that must be removed).

REGEXP_LIKE Oracle equivalent to count characters in Snowflake

I am trying to come up with an equivalent of the below Oracle statement in Snowflake. This would check if the different parts of the string separated by '.' matches the number of characters in the REGEXP_LIKE expression. I have come up with a rudimentary version to perform the check in Snowflake but I am sure there's a better and cleaner way to do it. I am looking to come up with a one-liner regular expression check in Snowflake similar to Oracle. Appreciate your help!
-- Oracle
SELECT -- would return True
CASE
WHEN REGEXP_LIKE('AB.XYX.12.34.5670.89', '^\w{2}\.\w{3}\.\w{2}') THEN 'True'
ELSE NULL
END AS abc
FROM DUAL
-- Snowflake
SELECT -- would return True
REGEXP_LIKE(SPLIT_PART('AB.XYX.12.34.5670.89', '.', 1), '[A-Z0-9]{2}') AND
REGEXP_LIKE(SPLIT_PART('AB.XYX.12.34.5670.89', '.', 2), '[A-Z0-9]{3}') AND
REGEXP_LIKE(SPLIT_PART('AB.XYX.12.34.5670.89', '.', 3), '[A-Z0-9]{2}') AS abc
You need to add a .* at the end as the REGEXP_LIKE adds explicit ^ && $ to string:
The function implicitly anchors a pattern at both ends (i.e. '' automatically becomes '^$', and 'ABC' automatically becomes '^ABC$'). To match any string starting with ABC, the pattern would be 'ABC.*'.
select
column1 as str,
REGEXP_LIKE(str, '\\w{2}\\.\\w{3}\\.\\w{2}.*') as oracle_way
FROM VALUES
('AB.XYX.12.34.5670.89')
;
gives:
STR
ORACLE_WAY
AB.XYX.12.34.5670.89
TRUE
Or in the context of your question:
SELECT IFF(REGEXP_LIKE('AB.XYX.12.34.5670.89', '\\w{2}\\.\\w{3}\\.\\w{2}.*'), 'True', null) AS abc;
Your use of \w seems to suggest you don't need delimited strings to be strictly [A-Z0-9] since word characters allow underscore and period. If all bets were off and the only requirement was to have . at 3rd, 7th and 10th position, you could have used like this way.
select 'AB.XGH.12.34.5670.89' like '__.___.__.%' ;

Oracle query to find any special character in first position or end position of the field value

I have a table in Oracle database with special characters attached at first and last position in the field value. I want to eliminate those special characters while querying the table. I have used INSTR function but I had to apply for each and every special character using CASE expression.
Is there a way to eliminate any special characters that is attached only at first and last positions in one shot?
The query I am using as is below:
CASE WHEN
INSTR(emp_address,'"')=1 THEN REPLACE((emp_address,'"', '').
.
.
.
You can use regular expressions to replace the leading and trailing character of a string if they match the regular expression pattern. For example, if your definition of a "special character" is anything that is not an alpha-numeric character then you can use the regular expression:
^ the start-of-the-string then
[^[:alnum:]] any single character that does not match the POSIX alpha-numeric character group
| or
[^[:alnum:]] any single character that does not match the POSIX alpha-numeric character group then
$ the end-of-the-string.
Like this:
SELECT emp_address,
REGEXP_REPLACE(
emp_address,
'^[^[:alnum:]]|[^[:alnum:]]$'
) AS simplified_emp_address
FROM table_name
Which, for the sample data:
CREATE TABLE table_name (emp_address) AS
SELECT 'test' FROM DUAL UNION ALL
SELECT '"test2"' FROM DUAL UNION ALL
SELECT 'Not "this" one' FROM DUAL;
Outputs:
EMP_ADDRESS
SIMPLIFIED_EMP_ADDRESS
test
test
"test2"
test2
Not "this" one
Not "this" one
If you have a more complicated definition of a special character then change the regular expression appropriately.
db<>fiddle here

WILDCARDS in SQL Oracle [duplicate]

This question already has answers here:
Can't we use [specifier] with like operator with Oracle?
(1 answer)
Query the list of CITY names starting with vowels (i.e., a, e, i, o, or u) from STATION
(18 answers)
Closed 3 years ago.
I am trying to find all the name that starts with either A,B or C in Oracle DB and I wrote this syntax:
SELECT NUME FROM JUCATORI
WHERE NUME LIKE '[ABC]%';
but it doesn't not give me any name (neither error), even though I am sure I have in my DB names that starts with either A,B or C.
LIKE doesn't work with character sets. (I think T-SQL extended LIKE to deal with such expressions, but Oracle's SQL doesn't.) You don't get an error, because LIKE '[ABC]%' looks for strings starting with an opening bracket, followed by an A, then a B, then a C, then a closing bracket
So either use OR:
SELECT nume FROM jucatori WHERE nume LIKE 'A%' OR nume LIKE 'B%' OR nume LIKE 'C%';
Or a regular expression:
SELECT nume FROM jucatori WHERE REGEXP_LIKE(nume, '^[ABC]');
One option is
where substr(nume, 1, 1) in ('A', 'B', 'C')
You're confusing regular expressions with 'like' conditions.
Like checks for exactly the string you pass to it, with the only three exceptions being:
1. % - any number of any characters
2. _ - any single character
3. ESCAPE clause that lets you define escape character
so you can use % as 'I'm looking for percent sign'
[ABC] meaning 'either A, B or C' is a regular expression syntax.
You may want to use regexp_like instead, or for such simple query just 'OR' several likes:
with examples as (
select 'Adam' ex from dual union all
select 'Dorothy' ex from dual union all
select '[ABC]something' ex from dual union all
select '[ABC]' from dual
)
select e.ex,
case when e.ex like '[ABC]%' then 'MATCHES' else null end as matches_like,
case when regexp_like(e.ex, '^[ABC].?') then 'MATCHES' else null end as matches_regexp_like,
case when e.ex like 'A%' or e.ex like 'B%' or e.ex like 'C%' then 'MATCHES' else null end as matches_complex_like
from examples e

Replacing multiple CHR() from PLSQL string

I have a PLSQL string which contains chr() special characters like chr(10), chr(13). I want to replace these special characters from the string. I tried the following ways
select regexp_replace('Hello chr(10)Goodchr(13)Morning','CHR(10)|chr(13)','') from dual;
This do not works since regexp_replace do not replace chr() function. Then I tried
select translate('Hello chr(10)Goodchr(13)Morning', 'chr(10)'||'chr(13)', ' ') from dual;
It works partially, ie; I am forced to replace chr() with white space(third parameter). No option if I do not want to replace chr() with white spaces . If I pass third character as null then above query returns null result.
Anybody have any other methods?
The problem with your replacement isn't the logic, it's the syntax. Parentheses are regex metacharacters, and as such, if you want to replace a literal parenthesis, you need to escape it. So your pattern should be this:
chr\(13\)|chr\(10\)
Here is a working query:
select
regexp_replace('Hello chr(10)Goodchr(13)Morning','chr\(13\)|chr\(10\)','', 1, 0, 'i')
from dual
The fifth parameters in the above call to regexp_replace is 'i' and indicates that we want to do a case insensitive replacement.
Demo
The above logic removes the literal text chr(13) and chr(10) from your text. If instead you want to remove the actual control characters chr(13) and chr(10), then you may add those control characters to the alternation, e.g.
select
regexp_replace('Hello chr(10)Goodchr(13)Morning','chr\(13\)|chr\(10\)|chr(10)|chr(13)','', 1, 0, 'i')
from dual
Since regular expression functions are relatively expensive in Oracle I think it's worth showing the alternate method which just uses REPLACE for the same effect.
This replaces occurrences of the each control characters with a space;
SELECT REPLACE(REPLACE('ABC'||CHR(10)||'DEF'||CHR(13)||'GHI'||CHR(10)||'JKL',CHR(13),' '),CHR(10),' ') from dual
And this replaces occurrences of the strings 'CHR(13)' and 'CHR(10)';
select REPLACE(REPLACE('ABCCHR(10)DEFCHR(13)GHICHR(10)JKL','CHR(13)',' '),'CHR(10)',' ') from dual

Resources