How to use subquery inside DECODE in Oracle - sql

I am trying to use a sub-query inside and Oracle Decode statement as shown below
RPAD(NVL(DECODE(TRIM(ST.StudentCode),'AB','CA','TM','CH',(Select InternalNumber from Address where State = SA.STATECODE) <=2,'PAS', ST.StudentCode), ' '), 3, ' ')
when I am running this part with my original query I am getting error as "Missing right paranthesis" in the same line. What is being wrong here?

Just use a single case expression:
RPAD( (CASE WHEN TRIM(ST.StudentCode) = 'AB' THEN 'CA',
WHEN TRIM(ST.StudentCode) = 'TM' THEN 'CH',
WHEN (Select a.InternalNumber from Address a where a.State = SA.STATECODE) <= 2 THEN 'PAS'
ELSE COALESCE(ST.StudentCode, ' '),
), 3, ' ')

You can add case expression inside your sub query:
RPAD(NVL(DECODE(TRIM(ST.StudentCode),'AB','CA','TM','CH',CASE WHEN (Select InternalNumber from Address where State = SA.STATECODE) <=2 THEN 'PAS' ELSE ST.StudentCode END), ' '), 3, ' ')
Oracle Database searches for the first WHEN ... THEN pair for which expr is equal to comparison_expr and returns return_expr. If none of the WHEN ... THEN pairs meet this condition, and an ELSE clause exists, then Oracle returns else_expr. Otherwise, Oracle returns null.

Related

condition where a <> ' ' and a <> '' not working

I wrote a SQL to query table mat from an oracle db where column A is not null. Column A is varchar and its default value is ' '. I wrote the sql below:
select * from mat where matnr='test' and A <>'' and A <> ' '
But it return an empty data set.
Then I ran:
select * from mat where matnr='test' and A <> ' '
This query worked. So what is the reason? Thx.
In Oracle, '' means NULL. Any direct comparison to NULL returns NULL instead of TRUE or FALSE, so you cannot say A <> '' - you must say A IS NOT NULL.
Another possibility would be to use the NVL function, replacing NULL with ' ', so that you could say
select * from mat where matnr='test' and NVL(A, ' ') <> ' '

Sql Bigquery - concat two columns into a new column

I want to concat two columns shown below into one new column.
I'm using this query:
SELECT
CONCAT( A_Bill_ID , ' ', B_BILL_ID ) AS BILL_ID
FROM
`table.tmp_140222`
From this query, the result will be like this.
My problem is I want to concat only columns that don't have a similar value so that the new column value will not duplicate two times. From the above result, the ID is duplicated since both of the columns has the same value.
Can anyone help me?
Thanks
You can use a case statement like this -
SELECT
case when A_Bill_ID = B_BILL_ID then a_bill_Id
else CONCAT(A_Bill_ID , ' ', B_BILL_ID )
end AS BILL_ID
FROM `table.tmp_140222`
If there are Null values in the initial columns, you can use IFNULL or COALEASE to replace that with an empty string. But in this case, I would suggest using this without a delimiter or writing multiple 'when' statements to avoid tailing spaces in the final column -
SELECT
case when A_Bill_ID = B_BILL_ID then a_bill_Id
else CONCAT(IFNULL(A_Bill_ID), ''), "", IFNULL(B_BILL_ID, ''))
end AS BILL_ID
FROM `table.tmp_140222`
select if (
a_bill_id = b_bill_id,
a_bill_id,
concat(a_bill_id , ' ', b_bill_id )
) as bill_id
from your_table
... shows null value ....
select if (
a_bill_id = b_bill_id or (a_bill_id = b_bill_id) is null,
coalesce(a_bill_id, b_bill_id),
concat(a_bill_id , ' ', b_bill_id )
) as bill_id
from your_table

LIKE statement to compare strings with hyphen

I am working in SQL and I have 3 columns Current Name, Given Full Name and Whether the names match (Y or No)
The problem with that is that when I am comparing the strings in the first 2 columns, it is not showing me the current result. For example, I am not finding a way to prove that 'Tushar Sharma' is same as 'Tushar-Sharma' considering that Tushar Sharma is the current full name and Tushar-Sharma is the name that has been extracted from a report.
I am stuck at the LIKE statement as to what to do if I want to have hyphen(-) included in the comparison so that I get a Y in the 3rd column.
Thank you
One option is to remove the hyphen for the comparison:
select (case when replace(given_name, '-', '') = replace(full_name, '-', '') then 'Y' else 'N' end) as names_match
You can use replace() with like as well:
select (case when replace(given_name, '-', '') like '%' + replace(full_name, '-', '') '%' then 'Y' else 'N' end) as names_match
Replace - with whitespace and compare, you can also use regex or fuzzy matching to improve the match for other conditions.
AND REPLACE(CurrentName, '-', ' ') = REPLACE(GivenName, '-', ' ');
Ex:
AND REPLACE('Tushar Sharma', '-', ' ') = REPLACE('Tushar-Sharma', '-', ' ')
will eval to
AND 'Tushar Sharma' = 'Tushar Sharma'
this will work:
select currentname,givenfullname,case when regexp_replace(currentname,' ','') like
regexp_replace(givenfullname,' ','') the 'Y' else 'N' end as matchstatus from
table_name;

sql length(null)

I have two columns: p.firstName and p.lastName.
Now I want to display the length of both names combined, the problem is, that in some fields of p.lastName the value "null" is stored.
When I try to do it like this:
LENGTH(p.firstName + p.lastName)
I get an error:
ORA-01722 invalid number
However, if I split it up
LENGTH(p.firstName) + LENGTH(p.lastName)
it doesn't give me an error message. But the length of the sum is NULL, even if the firstName does have a few characters. The NULL of p.LastName breaks it so to say.
Anyone has an idea?
You can Use IFNULL(), ISNULL(), COALESCE(), and NVL() Functions
SELECT LENGTH(COALESCE(p.firstName,'') + COALESCE(p.lastName,'')) AS Len FROM TableName
OR
SELECT LENGTH(ISNULL(p.firstName,'') + ISNULL(p.lastName,'')) AS Len FROM TableName
OR
SELECT LENGTH(IFNULL(p.firstName,'') + IFNULL(p.lastName,'')) AS Len FROM TableName
OR
SELECT LENGTH(NVL(p.firstName,'') + NVL(p.lastName,'')) AS Len FROM TableName
OR
SELECT LENGTH(p.firstName || p.lastName) AS Len FROM TableName
You may to concat columns instead using || operator:
LENGTH(p.firstName || p.lastName)
Example:
select ('abc'||null||'d') from dual; -- abcd
select length('abc'||null||'d') from dual; -- 4
Try this
select case when p.firstname is null then 0 else length(p.firstName) end +
case when p.lastName is null then 0 else
length(nickname) end from p
Oracle usually treats an empty string as NULL:
COALESCE(LENGTH(p.firstName), 0) + COALESCE(LENGTH(p.lastName),0)
I think it is much better to use it this way...
SELECT LENGTH(ISNULL(p.firstName,'') + ISNULL(p.lastName,'')) AS length FROM TableName
NOTE: Oracle behaves differently in the dealing of blank characters:
---------Oracle
SELECT LENGTH('') , LENGTH(null) FROM DUAL
--result: null,null
---------Postgress
SELECT LENGTH('') , LENGTH(null)
--result: 0,null
---------SQL Server
SELECT LEN('') , LEN(null)
--result: 0,null
---------MySQL
SELECT LENGTH('') , LENGTH(null)
--result: 0,null

using decode with input as comma separated list

This could be simple question for experts.
Here is my requirement. I have to use DECODE and match the string containing comma separated values.
Here is sample SQL: 'A' is column value from table, 'A,B'C' is comma separated string passed as expression to sql
SELECT DECODE('A' , 'A,B,C', 'true', 'false') FROM DUAL;
The above SQL should return true as csv expression contains 'A'.
Please help me writing this SQL
If I understand your question, you are trying to determine if a string is within another string?
select case when instr( 'A,B,C', 'A' ) > 0
then 'True'
else 'False'
end
from dual
Add the DECODE version
select decode( instr( 'A,B,C', 'A' ), 0, 'False', 'True' )
from dual
First, don't use decode(). Use the ANSI standard CASE statement. The answer to your question is that you can use LIKE:
SELECT (CASE WHEN ',' || 'A,B,C' || ',' LIKE '%,' || 'A' || ',%'
THEN 'true' ELSE 'false'
END)
FROM DUAL;
Note: The string concatenation is just because I suspect the values are variables. The simpler form is:
SELECT (CASE WHEN ',A,B,C,' LIKE '%,A,%'
THEN 'true' ELSE 'false'
END)
FROM DUAL;
Using DECODE, you can do it like this:
SELECT DECODE(INSTR('A,B,C', 'A'), 0, 'false', 'true') FROM DUAL;
where
INSTR('Comma separated string', 'column value to match') will return 0 if the column value is not in the comma separated string. In your example,
INSTR('A,B,C', 'A') will return a value greater than 0 and INSTR('D,B,C', 'A') will return 0. So then DECODE can check if the return value of INSTR() is 0 then return false otherwise return true.