How can I use "OR" condition in MySQL CASE expression? - mysql

I have a procedure that contains CASE expression statement like so:
BEGIN
....
WHILE counter < total DO
....
CASE ranking
WHEN 1 OR 51 OR 100 OR 167 THEN SET
project_name = 'alpha';
WHEN 2 THEN SET
project_name = 'beta';
WHEN 10 OR 31 OR 40 OR 61 THEN SET
project_name = 'charlie';
....
ELSE SET
project_name = 'zelta';
END CASE;
INSERT INTO project (id, name) VALUES (LAST_INSERT_ID(), project_name);
SET counter = counter + 1;
END WHILE;
END
$$
DELIMITER ;
When I call the above procedure, cases with OR statements are either skipped completely or only the first item in the list is matched. What am I doing wrong?

CASE ranking
WHEN 1 THEN 'alpha'
WHEN 2 THEN 'beta'
WHEN 10 THEN 'charlie'
ELSE 'zelta'
END CASE;
You can use one of expresions that WHEN has, but you cannot mix both of them.
1) WHEN when_expression
Is a simple expression to which input_expression is compared when the simple CASE format is used. when_expression is any valid expression. The data types of input_expression and each when_expression must be the same or must be an implicit conversion.
2) WHEN Boolean_expression
Is the Boolean expression evaluated when using the searched CASE format. Boolean_expression is any valid Boolean expression.
You could program:
1)
CASE ProductLine
WHEN 'R' THEN 'Road'
WHEN 'M' THEN 'Mountain'
WHEN 'T' THEN 'Touring'
WHEN 'S' THEN 'Other sale items'
ELSE 'Not for sale'
2)
CASE
WHEN ListPrice = 0 THEN 'Mfg item - not for resale'
WHEN ListPrice < 50 THEN 'Under $50'
WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
ELSE 'Over $1000'
END
But in any case you can expect that the variable ranking is going to be compared in a boolean expresion.
http://msdn.microsoft.com/en-us/library/ms181765.aspx

you can use in to compare the values both numeric or character
CASE
WHEN ranking in(1,2,3) THEN '1Q'
WHEN ranking in(4,5,6) THEN '2Q'
ELSE '3Q'
END CASE;
CASE
WHEN ranking in('1','2','3') THEN '1Q'
WHEN ranking in('4','5','6') THEN '2Q'
ELSE '3Q'
END CASE;
this will also work in select statement and stored procedure also.
select case when month(curdate()) in (4,5,6) then 1 when month(curdate()) in (7,8,9) then 2 else 3 end as fiscal_quarter ;

This is also possible:
select (case when (var1 = 0 or var2 = 1) then 'x' else 'y' end)
from...

Related

SQL query to get value based on some values in fields

I have a MySQL database with a table named generations the structure of the table is as follows
I want to get value 10 as output when ten_generation have value 1 otherwise it will not return any value, 20 as output if twenty_generation have value 1 otherwise it will not return any value, 30 as output if thirty_generation have value 1 otherwise it will not return any value. If all the three fields has a value 1 output will be 10,20,30 also the task_id will provided as the input.
Its unclear what you intend the output to be when multiple generation columns are 1 but one solution is to use a CASE statement:
SELECT CASE
WHEN ten_generation = 1 THEN 10
WHEN twenty_generation = 1 THEN 20
WHEN thirty_generation = 1 THEN 30
ELSE NULL
END AS value
FROM generations
WHERE id = :your_id
If you want it as multiple columns then:
SELECT CASE
WHEN ten_generation = 1
THEN 10
ELSE NULL
END AS ten_value,
CASE
WHEN twenty_generation = 1
THEN 20
ELSE NULL
END AS twenty_value,
CASE
WHEN thirty_generation = 1
THEN 30
ELSE NULL
END AS thirty_value
FROM generations
WHERE id = :your_id
if only twenty_generation contain value 1 the output is 20 and if twenty_generation and ten_generation contain value 1 output is 10,20
Oracle Query:
SELECT TRIM(
LEADING ',' FROM
CASE WHEN ten_generation = 1 THEN '10' END
|| CASE WHEN twenty_generation = 1 THEN ',20' END
|| CASE WHEN thirty_generation = 1 THEN ',30' END
) AS value
FROM generations
WHERE id = :your_id
For MySQL you'd use CONCAT_WS:
select
concat_ws(',',
case when ten_generation = 1 then '10' end,
case when twenty_generation = 1 then '20' end,
case when thirty_generation = 1 then '30' end
) as result
from mytable
where task_id = 2;

Combining multiple condition in single case statement

Does Invantive SQL support multiple condition in a single case statement? I the statement below, I did not get any results. Tried the same statement with only 1 condition (no cascade), this retrieved the expected result.
select prj.code
, prj.startdate
, prj.enddate
from exactonlinerest..projects prj
where prj.code between $P{P_PROJECT_FROM} and $P{P_PROJECT_TO}
and case
/* when (prj.enddate is null or prj.enddate >= sysdate)
then 'Y'
when (prj.enddate is not null and prj.enddate <= sysdate)
then 'N' */
when prj.startdate <= sysdate
then 'B'
end
= $P{P_PROJECT_ACTIVE_FROM}
I think you where clause is not correctly formulated. With Exact Online, a project either has:
option 1: no end date,
option 2: an end date in the past
option 3: or an end date in the future
The first part of the case handles option 1 and option 3. The second part handles option 2. So there is never an outcome of 'B' in the case.
To analyze such problems, I recommend include the case in the select clause and removing the filter. That gives you a view of the possible outcomes.
Example:
use 868056,102673
select prj.division
, prj.code
, prj.startdate
, prj.enddate
, case
when prj.enddate is null or prj.enddate >= sysdate
then 'Y'
when prj.enddate is not null and prj.enddate <= sysdate
then 'N'
when prj.startdate <= sysdate
then 'B'
end
indicator
from exactonlinerest..projects prj
where prj.code between $P{P_PROJECT_FROM} and $P{P_PROJECT_TO}

How to use case when in MySQL?

I use case when in MySQL like this:
select name, age, time, countDay, dvt, total, dateLogin,
(total - datediff(NOW(), dateLogin)) as totalVal18,
(total - age) as totalVal22
case dvt
when dvt = 0 then countDay = totalVal18
when dvt = 1 then countDay = totalVal22
Update 1:
Struct table is: dvt, total, countDay is double type.
dateLogin is datetime type.
User input is dateLogin and age.
Output using countDay to check values. Like:
where countDay >= 18.
dvt is tinyint. dvt like your age > 18 or age < 18
Error like:
error like case dvt
when dvt = 0 then at line 2
When using formula it happens error? How to using the formula in case when MySQL?
You have incorrectly combined the 2 versions of the case structure.
Either use
case dvt
when 0 then totalVal18
when 1 then totalVal22
end as countDay
Or
case
when dvt = 0 then totalVal18
when dvt = 1 then totalVal22
end as countDay
forms. See mysql's documentation on case
Update
You cannot use column aliases this way, you need to include the formula in the case statement as well.
Check this Sample Here table refers to your table name
SELECT CASE
WHEN dvt > 18 THEN 1
ELSE 0 END AS
countDay
FROM table

Select * from table WHERE `column` = x if `column` != -1

I need to make a select like,
Select * from table WHERE column = x if column != -1
but i have no idea for now.
Anyone know or made in past something like that?
Thanks.
You should also write like this,
Select * from table
WHERE
1 = case when column != -1 then
case when column = x then 1 else 0 end
else 1 end
You can utilize case when in where clause.
Similarly you can add more conditional criteria like,
Select * from table
WHERE
1 = case when column != -1 then
case when column = x then 1 else 0 end
else 1 end
AND
1 = case when column1 [conditional operator] value then
case when column1 = xx then 1 else 0 end
else 1 end
This is just an example how you can integrate more conditional criteria together, even though you can add more case when in else part even.

Scalar-valued function doesn't return expected result

I have created a scalar-valued function in Microsoft SSMS, it is as follows:
CREATE FUNCTION [dbo].[fGetCurrentBalFromName]
(
#Name NVarchar,
#CliFl Bit
)
RETURNS Money
AS
BEGIN
DECLARE #CurrentBal Money
select #CurrentBal=SUM(tt.Debt) from
(select case t.Clientfl when 1 then dbo.fGetClientNameFromId(t.AgentID)
else dbo.fGetSupplierNameFromId(t.AgentID)
end as Cli,
t.Clientfl,
case t.Clientfl when 1 then
case t.Incomfl
when 1 then t.Amount
else (-1)*t.Amount
end
else
case t.Incomfl
when 1 then (-1)*t.Amount
else t.Amount
end
end as Debt
from [Store].[dbo].[Money] t) tt where tt.Cli=#Name and tt.Clientfl=#CliFl
group by tt.Cli
RETURN #CurrentBal
END
When I execute
Select dbo.fGetCurrentBalFromName('Вали',1)
I get no(NULL) result.
But when I try to execute the query alone without parameters
select SUM(tt.Debt) from
(select case t.Clientfl when 1 then dbo.fGetClientNameFromId(t.AgentID)
else dbo.fGetSupplierNameFromId(t.AgentID)
end as Cli,
t.Clientfl,
case t.Clientfl when 1 then
case t.Incomfl
when 1 then t.Amount
else (-1)*t.Amount
end
else
case t.Incomfl
when 1 then (-1)*t.Amount
else t.Amount
end
end as Debt
from [Store].[dbo].[Money] t) tt where tt.Cli='Вали' and tt.Clientfl=1
group by tt.Cli
I get exactly what I want.
So what is the mistake I had done creating the scalar-valued function.
Any help will be appreciated!
You need to specify the size of the parameter #Name.
#Name NVarchar
Without size it defaults to 1 character.
Try something like this.
#Name NVarchar(100)
SQL Fiddle