if-elseif-else 'condition' in oracle SQL [duplicate] - sql

This question already has answers here:
Using IF ELSE in Oracle
(2 answers)
Closed 10 years ago.
I am wondering if there if possibility to achieve some thing like
'if-elseif-else' condition , i know there is a 'case-when-then-else' but it checks only one condition at a time (if i understand it correctly). How can i achieve if-elseif-else scenario in Oracle sql

You can use if/else using case statements like this.
SELECT ename, CASE WHEN sal = 1000 THEN 'Minimum wage'
WHEN sal > 1000 THEN 'Over paid'
ELSE 'Under paid'
END AS "Salary Status"
FROM emp;

i know there is a 'case-when-then-else' but it checks only one
condition at a time
What you are describing is a SIMPLE case. Oracle has two case types: SIMPLE and SEARCHED (see here for more info http://docs.oracle.com/cd/B19306_01/server.102/b14200/expressions004.htm)
SIMPLE
case A
when 1 then 'foo'
when 2 then 'bar'
else ..
end
SEARCHED
case
when A=1 and B='A' then 'foo'
when D + C =1 and B !='A' then 'Bar'
else ..
end
you probably want to use a searched case. You can use them in PL/SQL or SQL. eg in SQL
select ..
from table
where case
when A=1 and B='A' then 'foo'
when D + C =1 and B !='A' then 'Bar'
else ..
end = 'foo'

Look out for "Decode in Oracle"
decode( expression , search , result [, search , result]... [, default] )
It is similar to "if-elseif-else"
Refer: http://www.techonthenet.com/oracle/functions/decode.php
NOTE: It does only equality checks..

Related

Why ISNumeric() Transact-SQL function treats some var-chars as Int [duplicate]

This question already has answers here:
CAST and IsNumeric
(11 answers)
Closed 4 years ago.
SELECT some_column
FROM some_table
WHERE some_column = '3.'
Return row/rows
SELECT some_column
FROM some_table
WHERE ISNUMERIC(some_column) = 0
AND some_column IS NOT NULL
AND some_column <> ''
Does not return any non numeric row/rows. there is a row which has a column value of '3.'
Am i missing something. Please Advise.
I don't understand the question. ISNUMERIC('3.') returns 1. So it would not be returned by the second query. And, presumably, no other rows would either.
Perhaps you really intend: somecolumn not like '%[^0-9]%'. This will guarantee that somecolumn has only the digits from 0-9.
In SQL Server 2012+, you can also use try_convert(int, somecolumn) is not null.
ISNUMERIC() has some flaws. It can return True/1 for values that are clearly not numbers.
SELECT
ISNUMERIC('.'),
ISNUMERIC('$')
If this is causing you issues, try using TRY_PARSE()
SELECT
TRY_PARSE('2' AS INT)
You can use this and filter for non-null results.
SELECT some_column
FROM some_table
WHERE TRY_PARSE(some_column AS INT) IS NOT NULL
ISNUMERIC is a legacy function, I would don't like it personally. It does exactly what it's supposed to do which is usually not what you need ("Is Numeric" is a very subjective question in Computer Science.) I recently wrote this query to clarify things for some co-workers:
SELECT string = x, [isnumeric says...] = ISNUMERIC(x)
FROM (VALUES ('1,2,3,,'),(',,,,,,,,,,'),(N'﹩'),(N'$'),(N'¢'),('12,0'),(N'52,3,1.25'),
(N'-4,1'),(N'56.'),(N'5D105'),('1E1'),('\4'),(''),(N'\'),(N'₤'),(N'€')) x(x);
Returns:
string isnumeric says...
---------- -----------------
1,2,3,, 1
,,,,,,,,,, 1
﹩ 0
$ 1
¢ 0
12,0 1
52,3,1.25 1
-4,1 1
56. 1
5D105 1
1E1 1
\4 1
0
\ 1
₤ 1
€ 1
TRY_CAST or TRY_CONVERT, or WHERE somecolumn not like '%[^0-9]%' as Gordon said, could be a good alternative.
For performance reasons it might not be a bad idea to pre-aggregate, persist and index the column by adding a new computed column. E.g. something like
ALTER <your table>
ADD isGoodNumber AS (ABS(SIGN(PATINDEX('%[^0-9]%',<your column>))-1)
This would return a 1 for rows only containing digits or a 0 otherwise. You can then index isGoodNumber (you pick a better name) for better performance.

CASE expression - add one more condition to the WHEN part

I have created a PL/SQL function where I have a case expression in a SQL query. This is working fine, but when I add another when condition it will not compile. Even if I use when ... and 2 > 1, this is also not compiling.
In the below code, the commented part is not working properly.
What I want is to add one more check in my when clause. Please advise.
create or replace function FUNCTION_NAME (date1 in varchar2,value1 in varchar2)
RETURN date
IS
date2 date;
BEGIN
SELECT D DATE2
INTO DATE2 FROM (SELECT CASE (SELECT TO_DATE(MAX(G.DATE3),'DD-MON-YYYY')
FROM TABLE1 G,
TABLE2 N
WHERE G.DATE3=N.DATE3)
WHEN LAST_DAY(TO_DATE(DATE1,'DD-MON-YYYY'))
/* AND MONTHS_BETWEEN (LAST_DAY(TO_DATE(SYSDATE)),
LAST_DAY(TO_DATE(TO_CHAR(DATE1),'DD-MON-YYYY'))) */
THEN LAST_DAY(TO_DATE(DATE1,'DD-MON-YYYY'))
ELSE
TO_DATE('31-DEC-99','DD-MON-YYYY')
END D
FROM DUAL);
RETURN DATE2;
END;
What you have is a case expression (not a case statement).
Case expressions are of two kinds: "simple" (case <expr> when val1 then ... when val2 then... etc.) and "searched" ( case when condition1 then ... when condition2 then ... etc.)
You wrote your case expression as a simple case expression. You can't, then, add conditions to the WHEN part. You must change the case expression to be "searched" all the way through.
case when (select ...) = last_day(...) AND <your commented condition> THEN .....
EDIT - copying part of a clarifying comment below my Answer.
Simple case expression:
case x when 1 then ....
Can also be written as searched case expression:
case when x = 1 then ....
These two are logically equivalent. However, if we want to add "AND 3 > 1" to the WHEN part, that works only in the searched form of the case expression.
There are two flavours of CASE.
Simple CASE:
select case dummy
when 'X' then 1
end as case_demo
from dual;
Searched CASE:
select case
when dummy = 'X' then 1
end as case_demo
from dual;
In your query you are mixing them like this, which won't work:
select case dummy
when 'X' and 1 = 1
then 1
end as case_demo
from dual;
If you switch to a "searched CASE", then you can add more when conditions:
select case
when dummy = 'X' and 1 = 1
then 1
end as case_demo
from dual;

IF statement within a SELECT - SQL [duplicate]

This question already has answers here:
Not equal <> != operator on NULL
(10 answers)
Closed 4 years ago.
I'm trying to write a query, that selects a number of values. I only want it to select one of the values if it isn't null.
I'm trying to use a case when but it is erroring.
SELECT pick_no,
pd.product,
from_warehouse,
to_warehouse,
qty_pick,
qty_check,
qty_picked,
qty_checked,
long_description,
ROUND(qty_pick / stk.pallet_unit_qty, 2) as [PalletQty],
ph.date_picking,
stk.bin_no,
CASE WHEN qty_picked <> null
THEN ROUND(qty_picked / stk.pallet_unit_qty, 2) as [pltCheck]
ELSE '0' END
FROM
Null is a tricky beast, you can't use equality operands on it. Also your else clause was returning a CHAR when the first clause returns a FLOAT :
CASE WHEN qty_picked IS NOT NULL
THEN ROUND(qty_picked / stk.pallet_unit_qty, 2) as [pltCheck]
ELSE 0 END
A simpler way to achieve your goal is to use COALESCE :
COALESCE(ROUND(qty_picked / stk.pallet_unit_qty, 2),0) as [pltCheck]

Decode to Case Statement [duplicate]

This question already has answers here:
CASE vs. DECODE
(7 answers)
Closed 6 years ago.
I need to convert the below decode to Case statement in SQL. Tried multiple ways , not able to get it right.
select
DECODE(SIGN(A.column - to_date((
DECODE('10/01/2011',
'%',to_char(A.column,'mm/dd/yyyy'),'10/01/2011') ),
'mm/dd/yyyy')),
-1, 0,
A.Amount))
from A
select case
when to_date(nullif(:dt,'%'),'mm/dd/yyyy') > A.column
then 0
else A.Amount
end
from A
The best approach to handle such code is to remove it and find the original requirement.
I suspect it was such as
1) if '%' is passed return AMOUNT
2) if a date string is passed return AMOUNT if the COLUMN is greater or equal than the parameter
3) return 0 otherwise
This leads to following CASE statement
select A."COLUMN",
case when :1 = '%' then A.Amount
when A."COLUMN" >= to_date(:2,'mm/dd/yyyy') then A.Amount
else 0 end as amount
from A;

Oracle: How can I get a value 'TRUE' or 'FALSE' comparing two NUMBERS in a query?

I want to compare two numbers. Let's take i.e. 1 and 2.
I've tried to write the following query but it simply doesn't work as expected (Toad says: ORA-00923: FROM keyword not found where expected):
SELECT 1 > 2 from dual
The DECODE is something like a Switch case, so how can I get the result of an expression evalutation (i.e. a number comparison) putting it in the select list?
I have found a solution using a functions instead of an expression in the SELECT LIST: i.e.
select DECODE(SIGN(actual - target)
, -1, 'NO Bonus for you'
, 0,'Just made it'
, 1, 'Congrats, you are a winner')
from some_table
Is there a more elegant way?
Also how do I compare two dates?
There is no boolean types in sql (at least in oracle).
you can use case:
SELECT CASE when 1 > 2 THEN 1 ELSE 0 END FROM dual
But your solution (decode) is also good, read here
The SIGN() function is indeed probably the best way of classifying (in)equality that may be of interest to you if you want to test a > b, a = b and a < b, and it will accept date-date or numeric-numeric as an argument.
I'd use a Case statement by preference, rather than a decode.
Select
case sign(actual-target)
when -1 then ...
when 0 then ...
when 1 then ...
end
SELECT (CASE
WHEN (SIGN(actual - target) > 0 ) THEN
'NO Bonus for you'
ELSE
'Just made it' END)
FROM dual
you can compare two dates with sql
METHOD (1):
SELECT TO_DATE('01/01/2012') - TO_DATE('01/01/2012')
FROM DUAL--gives zero
METHOD (2):
SELECT CASE
when MONTHS_BETWEEN('01/01/2012','01/01/2010') > 0
THEN 'FIRST IS GREATER'
ELSE 'SECOND IS GREATER OR EQUAL' END
FROM dual
sorry i cant format the code the formatting toolbar disappeared !
do any one know why?