Quick SQL Syntax Question - sql

I have a standard insert into / select statement that is formatted similar to this:
insert into Table
( ...,
...)
select
field1,
field2,
field3,
field4,
fieldetc
from .... etc
There are three specific fields in the select statement that will need different values selected depending on another field, let's call it checker and the three fields are field2, field3, and field 4. The values will either be a 0 or in the other situation will need a case when. My question is, how do I format an if/else statement so it will work within the select statement? How I have it now is like this:
select
field1data,
if checker = 'A' or checker is null
begin
0,
0,
0,
end
else
begin
case when ... then ... else ... end,
case when ... then ... else ... end,
case when ... then ... else ... end,
end
fieldetcdata
from... etc
This is returning errors. How can I format this so it will work correctly, either selecting zeroes for these three fields or running through my case when statements in the other situation. Thanks!

You'll need to specify case statement for each field separately.
Select field1data,
Case When IsNull(Checker,'A') = 'A' Then 0
When Cond1 Then Whatever1
...
Else ...
End,
Case When IsNull(Checker,'A') = 'A' Then 0
When Cond2 Then Whatever1
...
Else ...
End,
Case When IsNull(Checker,'A') = 'A' Then 0
When Cond2 Then Whatever1
...
ELSE ...
End,
fieldetcdata
From ETC

Take out the IF and the BEGIN/END stuff and it should work. All you need to use is the
CASE COALESCE(checker,'A') WHEN 'A' THEN 0 ELSE alternate_value END
for each conditional value you want to SELECT
EDIT: Using your example:
SELECT
field1data,
CASE WHEN ISNULL(checker) THEN alternate_value1
WHEN checker = 'B' THEN alternate_value11 END,
CASE WHEN ISNULL(checker) THEN alternate_value2
WHEN checker = 'B' THEN alternate_value22 END,
CASE WHEN ISNULL(checker) THEN alternate_value3
WHEN checker = 'B' THEN alternate_value3 END,
fieldetcdata
FROM
TABLE
EDIT2: For multiple conditions, you simply add WHEN clauses.
http://msdn.microsoft.com/en-us/library/ms181765.aspx

Edited based on comments below.
You need to use a CASE statement with multiple WHEN conditions.
SELECT
field1data,
CASE COALESCE(checker, 'A') WHEN 'A' THEN 0 WHEN condition2 THEN ... ELSE ... END,
CASE COALESCE(checker, 'A') WHEN 'A' THEN 0 WHEN condition2 THEN ... ELSE ... END,
CASE COALESCE(checker, 'A') WHEN 'A' THEN 0 WHEN condition2 THEN ... ELSE ... END,
CASE COALESCE(checker, 'A') WHEN 'A' THEN 0 WHEN condition2 THEN ... ELSE ... END,
CASE COALESCE(checker, 'A') WHEN 'A' THEN 0 WHEN condition2 THEN ... ELSE ... END
FROM ...

Related

How to use Postgres CASE simple/short-hand syntax with multiple conditions?

I know with Postgres CASE expression, you can simplify it down to:
SELECT a,
CASE a WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
ELSE 'other'
END
FROM test;
...so you don't have to write etc...
CASE
WHEN a = 1 THEN ''
WHEN a = 2 THEN ''
.
..
...
WHEN a = 99 or a = 100 THEN ''
ELSE '' END
But is there a way to do this on multiple conditions with a keyword like ILIKE or LIKE? i.e.
SELECT a,
CASE a WHEN LIKE '1' or LIKE 'one' THEN 'one'
WHEN LIKE '2' and (LIKE 'two' or LIKE 'too') THEN 'two'
ELSE 'other'
END
FROM test;
Obviously this above doesn't work and I was trying some other variations but could not get it to work (if its possible)?
No, the short CASE syntax only works for a single condition per branch, and the comparison must be with the = operator. Use the other syntax for what you want.
You could use Postgres' regex operator here:
SELECT a,
CASE WHEN a ~ '^(1|one)$' THEN 'one'
WHEN a ~ '^(2|two)$' THEN 'two'
ELSE 'other'
END
FROM test;

SQL Ignore non matching columns

I'm trying to develop a stored procedure which does a select on a table. The stored procedure has 4 inputs: Input1, Input2, Input3, Input4.
Table has 4 columns: Col1,Col2,Col3, Col4.
The requirement is if there is no match on all selects, we need to ignore that and select pick next one:
Use case:
Select *
from table
where Col1=Input1
and Col2=Input2
and Col3=Input3
and Col4=Input4;
If there are no returns for the condition due to Col2 not equal to Input2, select needs to ignore it and try to match on others like:
Select *
from table
where Col1=Input1
and Col3=Input3
and Col4=Input4;
It should go like that till last possible option for the response:
Select *
from table
where Col1=Input1;
Please assist if there is a way and thanks in advance.
As it's mentioned in the comments, the question is a bit vague so I'm afraid any answer would be a bit vague too. You could do something like this:
select top 1 *,
case when Coll=input1 then 1 else 0 end as match1,
case when Col2=input2 then 1 else 0 end as match2,
case when Col3=input3 then 1 else 0 end as match3,
case when Col4=input4 then 1 else 0 end as match4
from table
order by match1+match2+match3+match4 desc
this is assuming SQL server as the DBMS (if it is Oracle, you may need to use LIMIT instead of TOP, for instance) and I also assumed that the columns have all the same weight in terms of matching.
Also, I'm assuming that you want only one of the best matches, if not you may need to do some changes to the TOP and/or use a where clause.
Finally, You may want to use isnull() if your columns and/or inputs are nullable.
Hmmm . . . One method is:
select t.*
from (select t.*,
sum(case when condition1 then 1 else 0 end) over () as c_1,
sum(case when condition1 and condition2 then 1 else 0 end) over () as c_12,
sum(case when condition1 and condition2 and condition3 then 1 else 0 end) over () as c_123,
sum(case when condition1 and condition2 and condition3 and condition4 then 1 else 0 end) over () as c_1234
from t
) t
where (c_1234 > 0 and condition1 and condition2 and condition3 and condition4) or
(c_1234 = 0 and c_123 > 0 and condition1 and condition2 and condition3) and
(c_123 = 0 and c_12 > 0 and condition1 and condition2 ) and
(c_12 = 0 and c_1 > 0 and condition1 ) ;
Depending on the conditions and other considerations -- such as whether you only expect one row -- there might be simpler methods.

Ignore else from CASE in SQL

Is there a way to avoid the else part when CASE is used ? For example below is the case STATUS column should display only A or B and there should not any NULL
(CASE
WHEN …..
THEN 'A'
WHEN …
THEN 'B'
END) as STATUS
Something like this:
SELECT *
FROM
(
SELECT
--ORIGINAL COLUMNS / EXPRESSIONS
, (CASE
WHEN ... THEN 'A'
WHEN ... THEN 'B'
END) as STATUS
FROM ...
)
WHERE STATUS IS NOT NULL

Case Statement embedded in NVL

I am trying to setup the below logic in as a divisor. I need to use NVL() to avoid the divide by zero error. I need to get a distinct count of the case statement.
Here is what I have:
(NVL(COUNT(DISTINCT
CASE WHEN ({field1} = 'a' OR {field1} = 'b' OR
{field1} = 'c' OR {field1} = 'd') AND
({field2} = 'a' OR {field2} = 'b') AND
({field3} > TO_DATE('01-JAN-2017', 'DD-MON-YYYY'))
THEN 1 END), 1))
There is something wrong with my syntax but cannot figure it out.
Any help would be appreciated. Thank you!
I changed lots of ORs to simpler IN
COUNT(DISTINCT
CASE
WHEN field1 IN ('a','b','c','d')
AND field2 IN ('a','b')
AND field3 > TO_DATE('01-JAN-2017', 'DD-MON-YYYY')
THEN 1
END)
COUNT(DISTINCT ...) doesn't return null, so removed redundant NVL
Now, the above will result is either 0 or 1.
You probably want this without distinct:
COUNT(
CASE
WHEN field1 IN ('a','b','c','d')
AND field2 IN ('a','b')
AND field3 > TO_DATE('01-JAN-2017', 'DD-MON-YYYY')
THEN 1
END)
Since, it is a divisor, it can't be 0, so you'll have to place safeguard for that. One sensible output in case the divisor is 0 is null. One way to achieve that is:
case when (expression) <> 0 then dividend/(expression) end

CASE statement equivalent to if or else-if

In this sql CASE statement:
CASE WHEN col1 = 'X' then 'A'
CASE when col2 = 'Y' then 'B'
else 'C' as result ...
if col1=X, and col2 = Y, will the output be 'A' or 'B' ? i.e. is the CASE statement functioning as an if or an else-if?
The evaluation of cases will terminate on the first one that evaluates to TRUE.