How to use case when in MySQL? - 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

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;

Case in the query gives undefined property error

I am trying to use CASE in my query. I have to calculate the difference between required_number and vehicle_quantity. If it is less than or equal to 0 then I need value 0 otherwise the difference value. I am trying following code directly in phpmyadmin. But I am getting error:
Notice in ./libraries/sql-parser/src/Utils/Query.php#427
Undefined property: SqlParser\Components\CaseExpression::$expr
This is the query I have tried so far.
SELECT
required_number,
vehicle_quantity,
CASE
WHEN (
required_number - vehicle_quantity
) <= 0 THEN
'0'
ELSE
(
required_number - vehicle_quantity
)
END AS income_amt
FROM
vehicles
WHERE
id = 22
Can anybody help me what mistake I did in my query. Thank You.
Try this:
SELECT required_number,
vehicle_quantity,
(CASE
WHEN ((required_number - vehicle_quantity) <=0) THEN 0
ELSE (required_number - vehicle_quantity)
END) AS extra
FROM vehicles
WHERE mun_id=22
TRY THIS: you have to use 0 instead of '0' because you are doing integer based calculation so you can't define string instead
SELECT
required_number,
vehicle_quantity,
CASE WHEN (required_number - vehicle_quantity) <= 0 THEN
0
ELSE
(required_number - vehicle_quantity)
END AS income_amt
FROM vehicles
WHERE id = 22

Error 1366 - Incorrect decimal value: '' for column '' at row -1

I've got a rather large query that is trying to get a list of carriers and compare the amount of insurance they have on record to identify carriers that do not meet a minimum threshold. If I run the select query it works just fine with no errors. But when I try to use it for an insert into a table it returns this error message
[Err] 1366 - Incorrect decimal value: '' for column '' at row -1
I have to use the cast as decimal at the bottom of this query because the value that is being stored in the database is a varchar and I cannot change that.
Anyone have any ideas?
set #cw_days = 15;
INSERT INTO carrier_dnl (carrier_id, dnl_reason_id, status_id)
SELECT work_cw_carrier_status_update.carrier_id, company_dnl_schema.dnl_reason_id,
CASE
WHEN work_cw_carrier_status_update.comparison_date > #cw_days THEN 1
ELSE 4
END as status
FROM work_cw_carrier_status_update
JOIN company_dnl_schema
ON company_dnl_schema.dnl_reason_id = 51
LEFT OUTER JOIN carrier_insurance
ON carrier_insurance.carrier_id = work_cw_carrier_status_update.carrier_id
WHERE ifnull(carrier_insurance.insurance_type_id,4) = 4
AND date(now()) BETWEEN IFNULL(carrier_insurance.insurance_effective_date,DATE_SUB(now(),INTERVAL 1 day)) AND IFNULL(carrier_insurance.insurance_expiration_date,DATE_ADD(now(),INTERVAL 1 day))
AND CASE WHEN NULLIF(carrier_insurance.insurance_bipdto_amount,'') is null THEN 0 < company_dnl_schema.value
ELSE
ifnull(cast(replace(carrier_insurance.insurance_bipdto_amount, '*','') as decimal),0) < company_dnl_schema.value
END
AND ( work_cw_carrier_status_update.b_bulk = 0 OR work_cw_carrier_status_update.b_bulk = 1 )
AND ( work_cw_carrier_status_update.b_otr = 1 OR work_cw_carrier_status_update.b_ltl = 1
OR work_cw_carrier_status_update.b_dray = 1 OR work_cw_carrier_status_update.b_rail = 1
OR work_cw_carrier_status_update.b_intermodal = 1 OR work_cw_carrier_status_update.b_forwarder = 1
OR work_cw_carrier_status_update.b_broker = 1 )
group by work_cw_carrier_status_update.carrier_id;`
If the select seems to work, then there are two possible problems. The first is that the select doesn't really work and the problem appears further down in the data. Returning one or a handful of rows is not always the same as "working".
The second is an incompatibility with the types for the insert. You can try to use silent conversion to convert the values in the select to numbers:
SELECT work_cw_carrier_status_update.carrier_id + 0, company_dnl_schema.dnl_reason_id + 0,
(CASE WHEN work_cw_carrier_status_update.comparison_date > #cw_days THEN 1
ELSE 4
END) as status
This may look ugly, but it is not nearly as ugly as storing ids as strings in one table and as numbers in another.

How to select a row by a certain amount of similar data

I'm about to build some sort of function or query where I can check if a certain record already exists in the database. The following rules apply:
The table has 6 columns
My yet-to-build-query has access to a complete row-object (all 6 values)
This query should find each row with at least 4 out of 6 corresponding values from the object I passed
Using MySQL
Is it even possible to build a query like this? My goal is to have a function which can return true if it's likely that a row like the passed object is already existing in the database.
Is my only option to make a query with multiple where-statements (where I try for each combination 4 different values)?
pseudo:
function getSimilarRow(Row_Object $row)
{
//select *
//from table_x
//where 4 out of 6 properties from object $row apply
}
You could use a case statement in the where clause for each property you are trying to match. If it meets the criteria then give the case statement a value of 1; if it doesn't then give it 0. The sum of the cases should then be >= 4.
I'm not that familiar with MySQL but the following will work (I knocked up a quick SQL Fiddle to show it working):
select * from SomeTable where
(case when propertyOne = 'value1' then 1 else 0 end) +
(case when propertyTwo = 'value2' then 1 else 0 end) +
(case when propertyThree = 'value3' then 1 else 0 end) +
(case when propertyFour = 'value4' then 1 else 0 end) +
(case when propertyFive = 'value5' then 1 else 0 end) +
(case when propertySix = 'value6' then 1 else 0 end) >= 4
Obviously you could change your logic in each clause if you'd prefer them to be likes or anything. You could even apply a weighting to each column by using something other than just 1 if you needed to get really creative.

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

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...