Replacing and removing leading characters - sql

I have this query
Select Distinct EMPLOYEE_ID from TABLE
and this returns bunch of EMPLOYEE ID's with leading zero's if the person's ID starts with 000 then it should be an 'e' and if it's 00 then it should be a 'u'
so for example if I have
0041258 this should show in the result as u41258 and if I have
00041258 then this should show as e41258
Is there a way to trim and replace in more efficient way that using substr and Case statement? and if no can you please show me how to use the substr and the Case statement in this case

Well, you can use case:
select (case when employee_id like '000%' then 'e' || substr(employee_id, 4)
when employee_id like '00%' then 'u' || substr(employee_id, 3)
else employee_id
end)
I doubt there is a much more efficient method than this.

Option that uses nested regular expressions:
SQL> with test (id) as
2 (select '0041258' from dual union
3 select '00041258' from dual
4 )
5 select id,
6 regexp_replace(regexp_replace(id, '^000', 'e'), '^00', 'u') result
7 from test;
ID RESULT
-------- --------------------
00041258 e41258
0041258 u41258
SQL>

Assuming you need to write an update statement (to permanently change the id's):
update <table>
set employee_id = case when employee_id like '000%'
then 'e' || substr(employee_id, 4)
else 'u' || substr(employee_id, 3) end
where employee_id like '00%'
;

Related

Concat subquery with other columns

I have a query that returns many columns concated with : ,
SELECT DECODE(ship_ps.STATUS, 'A', 'Y', 'N') AS isactive_ship
,ship_ps.party_site_id
,ship_ps.party_site_number AS site_number
,ship_ps.col1 || ship_ps.col 2
from ...
where ....
and i have a seprate query
(SELECT hp.party_name
FROM apps.hz_cust_accounts hca,apps.hz_parties hp
WHERE 1=1
AND hp.party_id=hca.party_id
AND hca.status='A'
AND hca.cust_account_id=:p_sold_to_org_id6)
i want to concat the result of it with ship_ps.col1 || ship_ps.col 2 || THE_QUERY
How to achieve that
Did you try to run the SQL and got an error?:
SQL> select dummy||' '||(select 1 from dual) from dual;
DUMMY||''||(SELECT1FROMDUAL)
------------------------------------------
X 1

Split a Column with Delimited Values and Compare Each Value

I have a column that contains multiple values in a delimited(comma-separated) format -
id | code
------------
1 11,19,21
2 55,87,33
3 3,11
4 11
I want to be able to compare to each value inside the 'code' column as below -
SELECT id FROM myTbl WHERE code = '11'
This should return -
1
3
4
I've tried the solution below but it does not work for all cases -
SELECT id FROM myTbl WHERE POSITION('11' IN code) <> 0
This will work with a 2 digit number like '11' as it will return a value that is <> 0 if it finds a match. But it will fail when searching for say '3' because rows with 'id' 2 and 3 both will be returned.
Here is link that talks about the POSITION function in REDSHIFT.
Any other approach that will solve this problem?
you can get the count of this string
SELECT id FROM myTbl WHERE regexp_count(user_action, '[11]') > 0
I think we can use regexp_substr() as follow.
select tb .id from myTbl tb where '11' in (
select regexp_substr( (select code from myTbl where id=tb.id),'[^,]+', 1, LEVEL) from dual
connect by regexp_substr((select code from myTbl where id=tb.id) , '[^,]+', 1, LEVEL) is not null);
just try this.
Use split_part() function
SELECT distinct id
FROM myTbl
WHERE '11' in ( split_part( code||',' , ',', 1 ),
split_part( code||',' , ',', 2 ),
split_part( code||',' , ',', 3 ) )
This is a very, very bad data model. You should be storing this information in a junction/association table, with one row per value.
But, if you have no choice, you can use like:
SELECT id
FROM myTbl
WHERE ',' || code || ',' LIKE '%,11,%';

How to parametrize SQL query, by passing multiple value

I have a SQL query, in where clause "MID = 123". I want to use a parameter for the VALUE and pass multiple values.
Example: now I am passing one VALUE of 123, but I want to pass multiple value like 123, 124, 125 etc. from which the SQL query will take values one by one and pass those to the where clause, and produce the result one by one, like first use value = 123, get the result, when use value = 124 and get results, and last use value = 125 to get results.
I need help with this parameter.
It will be great if we don't change the SQL query but we can parameter the where clause.
NOTE: I am using SQL Developer.
SQL query:
SELECT
'ABC' AS COLUMN_NAME,
(CASE
WHEN to_char(count(ABC)) > 1
AND to_char(max(ABC)) = to_char(min(ABC))
AND to_char(count(ABC)) = count(*)
AND to_char(max(ABC)) IS NULL
THEN 'same'
ELSE 'Diff'
END) AS COMPARISON_VALUE,
(CASE
WHEN to_char(COUNT(ABC)) = 1 OR to_char(min(ABC)) IS NULL
THEN 'No Values'
ELSE to_char(max(ABC))
END) AS TRANSACTION1,
to_char(min(ABC)) AS TRANSACTION2
FROM
ADVICES
WHERE
MID = '123';
One approach would be to specify the test data in a WITH clause and feed it to the query via an outer join. We include the test value as the first column in the result set. This means that every row in the result set will have the associated test value.
WITH testdata(testval) AS
(
SELECT '123' FROM DUAL UNION ALL
SELECT '124' FROM DUAL UNION ALL
SELECT '125' FROM DUAL
)
SELECT
testdata.testval,
...
...
FROM
ADVICES, testdata
WHERE
MID (+) = testdata.testval;
...i am trying to parameter the where clause, for which i want to fetch
parameter data from text or CSV should be fine.
Alternatively, testdata could be a table that's loaded from a CSV file with test values.
You may pass a CSV and use LIKE.
where ','||:var||',' like '%,'||MID||',%'
Example using HR schema
var myvar VARCHAR2
exec :myvar := '101,102,103' --parameter
select employee_id,department_id from employees where
','||:myvar||',' like '%,'||employee_id||',%';
Result
EMPLOYEE_ID DEPARTMENT_ID
----------- -------------
101 90
102 90
103 60
You can write your WHERE clause like the following:
WHERE MID IN
(SELECT
REGEXP_SUBSTR('YOUR_VALUE', '[^,]+', 1, LEVEL)
FROM
DUAL
CONNECT BY
REGEXP_SUBSTR('YOUR_VALUE', '[^,]+', 1, LEVEL) IS NOT NULL);
For checking the solution:
-- With multiple values
DEFINE YOUR_VALUE= '123,124,125';
SELECT
REGEXP_SUBSTR('&YOUR_VALUE', '[^,]+', 1, LEVEL)
FROM
DUAL
CONNECT BY
REGEXP_SUBSTR('&YOUR_VALUE', '[^,]+', 1, LEVEL) IS NOT NULL);
-- OUTPUT --
REGEXP_SUBS
-----------
123
124
125
-- With single value
DEFINE YOUR_VALUE = '123';
SELECT
REGEXP_SUBSTR('&YOUR_VALUE', '[^,]+', 1, LEVEL)
FROM
DUAL
CONNECT BY
REGEXP_SUBSTR('&YOUR_VALUE', '[^,]+', 1, LEVEL) IS NOT NULL;
-- OUTPUT --
REGEXP_SUBS
-----------
123
Cheers!!
You can change your where clause to -
WHERE
MID IN (YOUR_PARAMETER);
When you will pass multiple values, it will simply converted to OR condition and will fetch the results.

Oracle Regex at least "1" match in a serie

I have a question related with oracle sql regex function.
I have a series of zeros and ones. It can vary as:
Ex:
1111000
000001
0101111
10000
If there is at least one "1" in this serie, then I want to output as "1"
otherwise I want to ouput "0". So I tried something like:
SELECT REGEXP_REPLACE('1,1,1,0','[0,]||[1]+','') FROM DUAL
However this just outputs "1's" out of series excluding "0"
So my question: How can I achieve this on oracle sql?
If I understand well and you only need to check whether a string contains '1' or not, you may not need regexp and INSTR could be enough:
select case
when instr(yourString, '1') = 0
then '1 is not in the string'
else '1 is in the string'
end
from dual
`LIKE %1%' will work for you as well...
with dt as (
select '00000000' seq from dual union all
select '00011000' seq from dual)
select
seq,
case when seq like '%1%' then 1 else 0 end as res
from dt;
SEQ RES
-------- ----------
00000000 0
00011000 1
Later on I also figured out that this also worked for me:
SELECT
REGEXP_REPLACE( 'MY_STRING' , '.?+1?[0,]', '') as COLUMN_NAME
FROM dual;

SQL Search rows that contain strings from 2nd table list

I have a master table that contains a list of strings to search for. it returns TRUE/FALSE if any string in the cell contains text from the master lookup table. Currently I use excel's
=SUMPRODUCT(--ISNUMBER(SEARCH(masterTable,[#searchString])))>0
is there a way to do something like this in SQL? LEFT JOIN or OUTER APPLY would be simple solutions if the strings were equal; but they need be contains..
SELECT *
FROM t
WHERE col1 contains(lookupString,lookupColumn)
--that 2nd table could be maintained and referenced from multiple queries
hop
bell
PRS
2017
My desired results would be a column that shows TRUE/FALSE if the row contains any string from the lookup table
SEARCH_STRING Contained_in_lookup_column
hopping TRUE
root FALSE
Job2017 TRUE
PRS_tool TRUE
hand FALSE
Sorry i dont have access to the DB now to confirm the syntax, but should be something like this:
SELECT t.name,
case when (select count(1) from data_table where data_col like '%' || t.name || '%' > 0) then 'TRUE' else 'FALSE' end
FROM t;
or
SELECT t.name,
case when exists(select null from data_table where data_col like '%' || t.name || '%') then 'TRUE' else 'FALSE' end
FROM t;
Sérgio
You can use a combination of % wildcards with LIKE and EXISTS.
Example (using Oracle syntax) - we have a v_data table containing the data and a v_queries table containing the query terms:
with v_data (pk, value) as (
select 1, 'The quick brown fox jumps over the lazy dog' from dual union all
select 2, 'Yabba dabba doo' from dual union all
select 3, 'forty-two' from dual
),
v_queries (text) as (
select 'quick' from dual union all
select 'forty' from dual
)
select * from v_data d
where exists (
select null
from v_queries q
where d.value like '%' || q.text || '%');