CASE with AS query - mysql

I have about the following query:
SELECT *
FROM Product
ORDER BY (SELECT CASE
(SELECT MIN(date) FROM SomethingElse WHERE productId = Product.id) AS here
WHEN NULL
THEN 0
ELSE here
) DESC
However, AS in CASE doesn't work. I need a way to save the value in a variable and use it again.

So you are trying to do CASE when expression IS NULL THEN 0 ELSE expression END?
In this case you can just use COALESCE(expression, 0)

Related

How return a value with mysql query depending on condition?

I have the next mysql table:
Table(cl_convenios_do_medico)
id auto_increment
med_id int
conv_id int
I´d like a sql to return '1':
If I found at least one "med_id" having a "conv_id".
If the table is empty
otherwise return '0'
I have tried something as:
select IFNULL( (select '1' from cl_convenios_do_medico CC where
CC.med_id=<my_med_id> and CC.conv_id=<my_conv_id> )
and exists(select '1' from cl_convenios_do_medico CC where CC.med_id=<my_med_id> limit 1),'0') as result
If seems to work when the table is not empty, but fail if table is empty.
Maybe someone has a simpler solution.
Do something like this
SELECT MAX(result)
FROM (
SELECT CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS result
FROM cl_convenios_do_medico
WHERE med_id = 8
AND conv_id = 9
UNION
SELECT CASE WHEN COUNT(*) = 0 THEN 1 ELSE 0 END
FROM cl_convenios_do_medico
) c
DEMO
You can use CASE statement
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
WHEN conditionN THEN resultN
ELSE result
END;
for example
SELECT CASE WHEN (SELECT COUNT(*) FROM employee) > 1 THEN '1' ELSE '0' END

GROUP BY WITH CASE

I want to select a table with group by like this:
and i want to have a result like this
i compare the state, if i have one up state so the result will up
SELECT name,MAX(state)
FROM table
GROUP BY name
Because state is a varchar (assumption), the maximum is an alphabetical order, favouring 'up'.
If its an enum, it still will work if 'up' is the second element of the enum.
Try this:
Demo on DB Fiddle
select
name,
case
when max(state = 'up') then 'up'
else 'down'
end state
from
mytable
group by name;
result:
name | state
PLR | up
VRL | down
Please, try with below query:
select A.name, (case when A.up_state>0 then 'up' else 'down' end) as state
from (
select name, sum(case when state='up' then 1 else 0 end) as up_state
from table_name
group by name
) as A

MySQL group by empty and non-empty values

At present, I have something like:
select sum(total) from table_name where field != ''
UNION
select sum(total) from table_name where field = ''
It works but I'm curious if it is possible to use "group by" to filter by empty and non-empty values?
select SUM(CASE WHEN field != '' THEN total ELSE 0) NONEMPTY,
SUM(CASE WHEN field = '' THEN total ELSE 0) EMPTY from table_name
Try above query.
Here i had used CASE WHEN.

Simplify CASE expression used multiple times

For readability, I would like to modify the below statement. Is there a way to extract the CASE statement, so I can use it multiple times without having to write it out every time?
select
mturk_worker.notes,
worker_id,
count(worker_id) answers,
count(episode_has_accepted_imdb_url) scored,
sum( case when isnull(imdb_url) and isnull(accepted_imdb_url) then 1
when imdb_url = accepted_imdb_url then 1
else 0 end ) correct,
100 * ( sum( case when isnull(imdb_url) and isnull(accepted_imdb_url) then 1
when imdb_url = accepted_imdb_url then 1
else 0 end)
/ count(episode_has_accepted_imdb_url) ) percentage
from
mturk_completion
inner join mturk_worker using (worker_id)
where
timestamp > '2015-02-01'
group by
worker_id
order by
percentage desc,
correct desc
You can actually eliminate the case statements. MySQL will interpret boolean expressions as integers in a numeric context (with 1 being true and 0 being false):
select mturk_worker.notes, worker_id, count(worker_id) answers,
count(episode_has_accepted_imdb_url) scored,
sum(imdb_url = accepted_imdb_url or imdb_url is null and accepted_idb_url is null) as correct,
(100 * sum(imdb_url = accepted_imdb_url or imdb_url is null and accepted_idb_url is null) / count(episode_has_accepted_imdb_url)
) as percentage
from mturk_completion inner join
mturk_worker
using (worker_id)
where timestamp > '2015-02-01'
group by worker_id
order by percentage desc, correct desc;
If you like, you can simplify it further by using the null-safe equals operator:
select mturk_worker.notes, worker_id, count(worker_id) answers,
count(episode_has_accepted_imdb_url) scored,
sum(imdb_url <=> accepted_imdb_url) as correct,
(100 * sum(imdb_url <=> accepted_imdb_url) / count(episode_has_accepted_imdb_url)
) as percentage
from mturk_completion inner join
mturk_worker
using (worker_id)
where timestamp > '2015-02-01'
group by worker_id
order by percentage desc, correct desc;
This isn't standard SQL, but it is perfectly fine in MySQL.
Otherwise, you would need to use a subquery, and there is additional overhead in MySQL associated with subqueries.

how do I write an IF ELSE into this query to make it work?

table looks something like this: (yes those are & signs. ignore the dashes)
ID-VALUE-NUM
-1-YES----2-
-1-NO-----3-
-2-YES----1-
-2-NO-----1-
-3-&&&----1-
-3-&------2-
-3-&&-----2-
what I need to do:
for each ID, I need to get the value with the highest NUM, in the case of a tie and VALUE has &s then it would pick the shortest. if the value is YES/NO then it will pick YES.
result desired
ID-VALUE-NUM
-1-NO-----3-
-2-YES----1-
-3-&------2-
I think I have to put a IF statement in there somewhere but I'm not sure how.
Here is one way. The join finds the maximum num. Then the select uses logic to choose the right value based on your rules:
select t.id,
(case when count(*) = 1 then min(value)
when max(value like '%&%') > 0 then min(value)
when max(value = 'Yes') > 0 and max(value = 'No') > 0 then 'Yes'
else max(value)
end) as value,
t.num
from t join
(select id, max(num) as maxnum
from t
group by id
) tm
on t.id = tm.id and t.num = tm.maxnum
group by t.id, t.num