statement in sql - sql

There are rows. They are separated by a comma-separated values. How do I bring only one example. (1) My solution does not work.
SELECT VB.COL
FROM (SELECT '21,31' AS COL
FROM DUAL
UNION ALL
SELECT '1' AS COL
FROM DUAL
UNION ALL
SELECT '21,31,1' AS COL
FROM DUAL
UNION ALL
SELECT '156,158' AS COL
FROM DUAL
) VB
WHERE VB.COL LIKE '%'||1||'%';

Storing lists of numbers as a comma-separated string is a bad, bad idea. It is not the SQL way of storing lists. If you have any control over the database, then create a proper junction table.
Sometimes, we are stuck with other people's bad design decisions. In that case, you can use LIKE, but you should include the delimiters:
WHERE ',' || VB.COL || ',' LIKE '%,' || 1 || ',%';
The delimiters prevent "1" from matching "31" and "21".

I think you want to bring output string where only '1' is available.
Please let me know if i am wrong. because not able to understand your required output. I will change query accordingly if required.
SELECT VB.COL
FROM (SELECT '21,31' AS COL
FROM DUAL
UNION ALL
SELECT '1' AS COL
FROM DUAL
UNION ALL
SELECT '21,31,1' AS COL
FROM DUAL
UNION ALL
SELECT '156,158' AS COL
FROM DUAL
) VB
WHERE REGEXP_LIKE (VB.COL,'^1$');

Related

Regexp pattern for special characters

I have the data in the format like
Input:
Code_1
FAB
?
USP BEN,
.
-
,
Output:
Code_1
FAB
IP BEN,
I need to exclude only the value which have length as 1 and and are special characters
I am using (regexp_like(code_1,'^[^<>{}"/|;:.,~!?##$%^=&*\]\\()\[¿§«»ω⊙¤°℃℉€¥£¢¡®©0-9_+]')) AND LENGTH(CODE_1)>=1
I have also tried REGEXP_LIKE(CODE_1,'[A-Za-z0-9]')
Based on your requirements which I understand are you want data that is not single character AND non-alpha numeric (at the same time), this should do it for you.
The 'WITH' clause just sets up test data in this case and can be thought of like a temp table here. It is a great way to help people help you by setting up test data. Always include data you don't expect!
The actual query starts below and selects data that uses grouping to get the data that is NOT a group of non-alpha numeric with a length of one. It uses a POSIX shortcut of [:alnum:] to indicate [A-Za-z0-9].
Note your requirements will allow multiple non-alnum characters to be selected as is indicated by the test data.
WITH tbl(DATA) AS (
SELECT 'FAB' FROM dual UNION ALL
SELECT '?' FROM dual UNION ALL
SELECT 'USP BEN,' FROM dual UNION ALL
SELECT '.' FROM dual UNION ALL
SELECT '-' FROM dual UNION ALL
SELECT '----' FROM dual UNION ALL
SELECT ',' FROM dual UNION ALL
SELECT 'A' FROM dual UNION ALL
SELECT 'b' FROM dual UNION ALL
SELECT '5' FROM dual
)
SELECT DATA
FROM tbl
WHERE NOT (REGEXP_LIKE(DATA, '[^[:alnum:]]')
AND LENGTH(DATA) = 1);
DATA
----------
FAB
USP BEN,
----
A
b
5
6 rows selected.

Find value that is not a number or a predefined string

I have to test a column of a sql table for invalid values and for NULL.
Valid values are: Any number and the string 'n.v.' (with and without the dots and in every possible combination as listed in my sql command)
So far, I've tried this:
select count(*)
from table1
where column1 is null
or not REGEXP_LIKE(column1, '^[0-9,nv,Nv,nV,NV,n.v,N.v,n.V,N.V]+$');
The regular expression also matches the single character values 'n','N','v','V' (with and without a following dot). This shouldn't be the case, because I only want the exact character combinations as written in the sql command to be matched. I guess the problem has to do with using REGEXP_LIKE. Any ideas?
I guess this regexp will work:
NOT REGEXP_LIKE(column1, '^([0-9]+|n\.?v\.?)$', 'i')
Note that , is not a separator, . means any character, \. means the dot character itself and 'i' flag could be used to ignore case instead of hard coding all combinations of upper and lower case characters.
No need to use regexp (performance will increase by large data) - plain old TRANSLATE is good enough for your validation.
Note that the first translate(column1,'x0123456789','x') remove all numeric charcters from the string, so if you end with nullthe string is OK.
The second translate(lower(column1),'x.','x') removes all dots from the lowered string so you expect the result nv.
To avoid cases as n.....v.... you also limit the string length.
select
column1,
case when
translate(column1,'x0123456789','x') is null or /* numeric string */
translate(lower(column1),'x.','x') = 'nv' and length(column1) <= 4 then 'OK'
end as status
from table1
COLUMN1 STATUS
--------- ------
1010101 OK
1012828n
1012828nv
n.....v....
n.V OK
Test data
create table table1 as
select '1010101' column1 from dual union all -- OK numbers
select '1012828n' from dual union all -- invalid
select '1012828nv' from dual union all -- invalid
select 'n.....v....' from dual union all -- invalid
select 'n.V' from dual; -- OK nv
You can use:
select count(*)
from table1
WHERE TRANSLATE(column1, ' 0123456789', ' ') IS NULL
OR LOWER(column1) IN ('nv', 'n.v', 'nv.', 'n.v.');
Which, for the sample data:
CREATE TABLE table1 (column1) AS
SELECT '12345' FROM DUAL UNION ALL
SELECT 'nv' FROM DUAL UNION ALL
SELECT 'NV' FROM DUAL UNION ALL
SELECT 'nV' FROM DUAL UNION ALL
SELECT 'n.V.' FROM DUAL UNION ALL
SELECT '...................n.V.....................' FROM DUAL UNION ALL
SELECT '..nV' FROM DUAL UNION ALL
SELECT 'n..V' FROM DUAL UNION ALL
SELECT 'nV..' FROM DUAL UNION ALL
SELECT 'xyz' FROM DUAL UNION ALL
SELECT '123nv' FROM DUAL;
Outputs:
COUNT(*)
5
or, if you want any quantity of . then:
select count(*)
from table1
WHERE TRANSLATE(column1, ' 0123456789', ' ') IS NULL
OR REPLACE(LOWER(column1), '.') = 'nv';
Which outputs:
COUNT(*)
9
db<>fiddle here

Ltrim trimming extra character

I have the below code:
SELECT
ltrim('REASON_ACTIVE_DCA', 'REASON_') reason
FROM
dual
However, I'm obtaining '_CTIVE_DCA'. What's happening and how can I get 'ACTIVE_DCA' with ltrim?
Because LTRIM() removes all the characters as a set. So all leading "R"s and "E"s and so on removed. In fact, the ordering of the characters in the second string is irrelevant, so you would get the same result with '_NOSAER'.
If you want to remove the leading string of REASON_ -- if present -- then you don't use trim(). Instead, one method is:
select (case when 'REASON_ACTIVE_DCA' LIKE 'REASON$_%' ESCAPE '$'
then substr('REASON_ACTIVE_DCA', 8)
else 'REASON_ACTIVE_DCA'
end)
There are other ways, such as:
select regexp_replace('REASON_ACTIVE_DCA', '^REASON_', '')
I would do it with regular string functions (not regular expressions), and using INSTR instead of LIKE so I don't have to worry about escaping underscore.
Something like this - including a few sample strings in the WITH clause for testing:
with
inputs (i_str) as (
select 'REASON_ACTIVE_DCA' from dual union all
select 'REASON_NOT_GIVEN' from dual union all
select null from dual union all
select 'REASON-SPECIAL' from dual union all
select 'REASON_' from dual union all
select 'REASON' from dual
)
select i_str, substr(i_str, case instr(i_str, 'REASON_')
when 1 then 1 + length('REASON_')
else 1 end) as new_str
from inputs;
I_STR NEW_STR
----------------- -----------------
REASON_ACTIVE_DCA ACTIVE_DCA
REASON_NOT_GIVEN NOT_GIVEN
REASON-SPECIAL REASON-SPECIAL
REASON_
REASON REASON

Using REGXP_LIKE within queryExecute()

I'm looking to modify an existing query to use REGEXP_LIKE but falling foul of some syntax I'm not understanding properly. We've currently a CF query into an Oracle DB using the following:
result = QueryExecute("
SELECT paramOne, paramTwo FROM someTable WHERE fieldOne = :PUBLISHER
", {PUBLISHER=publisherId}, {datasource="someDB"});
which works. However, I want to modify the underlying query to be:
result = QueryExecute("
SELECT paramOne, paramTwo FROM someTable WHERE REGEXP_LIKE(fieldOne, '(^|,)(:PUBLISHER)($|,)', 'i')
", {PUBLISHER=publisherId}, {datasource="someDB"});
but it's not delivering the expected results. A few things I've noted as I try to debug...
The underlying query(without using a variable) works and has been verified in Oracle SQL
If I go to the source code and replace :PUBLISHER with a 'hard coded' value the things work as expected.
I've tried escaping the ':' but that's not the answer.
I fell there's something I'm not understanding about passing variables into a REGEX expression within queryExecute(), so would appreciate any thoughts.
Any input gratefully received,
Phil
SQL>
with t (fieldOne) as (
select 'abc, def' from dual union all
select 'def cba' from dual union all
select ':publisher' from dual
)
select * from t where REGEXP_LIKE(fieldOne, '(^|,)(:PUBLISHER)($|,)', 'i');
FIELDONE
----------
:publisher
SQL>
with t (fieldOne) as (
select 'abc, def' from dual union all
select 'def cba' from dual union all
select ':publisher' from dual
)
select * from t where REGEXP_LIKE(fieldOne, '(^|,)(' || :PUBLISHER || ')($|,)', 'i');
FIELDONE
----------
abc, def

How to cut everything after a specific character, but in case string doesn't contain it do nothing?

Let's say i have following data:
fjflka, kdjf
ssssllkjf fkdsjl
skfjjsld, kjl
jdkfjlj, ksd
lkjlkj hjk
I want to cut out everything after ',' but in case the string doesn't contain this character, it wont do anything, if i use substr and cut everything after ',' the string which doesn't contain this character shows as null. How do i achieve this? Im using oracle 11g.
This should work. Simply use regexp_substr
with t_view as (
select 'fjflka, kdjf' as text from dual union
select 'ssssllkjf fkdsjl' from dual union
select 'skfjjsld, kjl' from dual union
select 'jdkfjlj, ksd' from dual union
select 'lkjlkj hjk' from dual
)
select text,regexp_substr(text,'[^,]+',1,1) from t_view;
Assuming your table :
SQL> desc mytable
s varchar2(100)
you may use:
select decode(instr(s,','),0,s,substr(s,1,instr(s,',')-1)) from mytable;
demo
Well the below query works as per your requirement.
with mytable as
(select 'aaasfasf wqwe' s from dual
union all
select 'aaasfasf, wqwe' s from dual)
select s,substr(s||',',1,instr(s||',',',')-1) from mytable;