How do I update a table and set different values upon the condition evaluating to True.
For instance :
UPDATE Table
SET A = '1' IF A > 0 AND A < 1
SET A = '2' IF A > 1 AND A < 2
WHERE A IS NOT NULL;
I have seen CASE expression and IF expression in Procedures and Functions but I want to use it in a simple update/select statement. Is it possible or am I expecting too much from this lovely open source database?
UPDATE table
SET A = IF(A > 0 AND A < 1, 1, IF(A > 1 AND A < 2, 2, A))
WHERE A IS NOT NULL;
you might want to use CEIL() if A is always a floating point value > 0 and <= 2
Whilst you certainly can use MySQL's IF() control flow function as demonstrated by dbemerlin's answer, I suspect it might be a little clearer to the reader (i.e. yourself, and any future developers who might pick up your code in the future) to use a CASE expression instead:
UPDATE Table
SET A = CASE
WHEN A > 0 AND A < 1 THEN 1
WHEN A > 1 AND A < 2 THEN 2
ELSE A
END
WHERE A IS NOT NULL
Of course, in this specific example it's a little wasteful to set A to itself in the ELSE clause—better entirely to filter such conditions from the UPDATE, via the WHERE clause:
UPDATE Table
SET A = CASE
WHEN A > 0 AND A < 1 THEN 1
WHEN A > 1 AND A < 2 THEN 2
END
WHERE (A > 0 AND A < 1) OR (A > 1 AND A < 2)
(The inequalities entail A IS NOT NULL).
Or, if you want the intervals to be closed rather than open (note that this would set values of 0 to 1—if that is undesirable, one could explicitly filter such cases in the WHERE clause, or else add a higher precedence WHEN condition):
UPDATE Table
SET A = CASE
WHEN A BETWEEN 0 AND 1 THEN 1
WHEN A BETWEEN 1 AND 2 THEN 2
END
WHERE A BETWEEN 0 AND 2
Though, as dbmerlin also pointed out, for this specific situation you could consider using CEIL() instead:
UPDATE Table SET A = CEIL(A) WHERE A BETWEEN 0 AND 2
Here's a query to update a table based on a comparison of another table. If record is not found in tableB, it will update the "active" value to "n". If it's found, will set the value to NULL
UPDATE tableA
LEFT JOIN tableB ON tableA.id = tableB.id
SET active = IF(tableB.id IS NULL, 'n', NULL)";
Hope this helps someone else.
Related
We are using MySQL 8 as our java application DB.
We have a query with the following format:
select
id,
group_concat(NAME ORDER BY ID separator ',,') AS Code,
CASE
WHEN MAX(p.VARIABLEfactor) = 1 THEN MAX(i.factor) ELSE MAX(p.factor) END AS factor
from MA_TABLE
join TABLE_P p on (...)
join TABLE_I i on (...)
group by id
The query worked very fine in our development environments until deploy with client where the factor column is getting null.
We have run the same query in the client environment from MySQL Workbench and we can see that the factor column is getting well populated.
After some debugging,we changed :
CASE
WHEN MAX(p.VARIABLEfactor) = 1 THEN MAX(i.factor) ELSE MAX(p.factor) END AS factor
to
MAX(
WHEN p.VARIABLEfactor = 1 THEN i.factor ELSE p.factor END ) AS factor,
and the query worked correctly.
Any help here please?
From your explanation I gather that you don't understand the difference of your two case expressions. But they are very different. Let's look at an example for one ID:
ID
VARIABLEfactor
i.factor
p.factor
100
0
null
10
100
1
null
20
Your expression
CASE WHEN MAX(p.VARIABLEfactor) = 1 THEN MAX(i.factor) ELSE MAX(p.factor) END
looks at the maximum VARIABLEfactor, which is 1, so the THEN case applies and the maximum i.factor is returned. This is null, as all i.factor are null.
Your expression
MAX(WHEN p.VARIABLEfactor = 1 THEN i.factor ELSE p.factor END)
looks at each row's VARIABLEfactor. For the first row this is 0, so the ELSE case applies and p.factor 10 is used. For the second row the VARIABLEfactor is 1, so its i.factor null gets used. Of these you take the maximum, which is 10.
To recap: The first expression is just a CASE expression on the aggregation results. It returns null here. The second expression is a conditional aggregation. It returns 10 for the sample data.
Is there any way to find values that meet any m conditions out of given n conditions? For instance, if there are 10 conditions, and I want to find values that meet any 2 of them.
Use CASE expressions in the WHERE clause, 1 for each condition like this:
WHERE 2 =
CASE WHEN <condition1> THEN 1 ELSE 0 END +
CASE WHEN <condition2> THEN 1 ELSE 0 END +
CASE WHEN <condition3> THEN 1 ELSE 0 END +
..........................................
You can change the = sign to > or < to meet your requirement.
There is. It's not gonna be pretty though.
Start with your conditions as SELECT expressions.
select T.*,
case
when T.SOME_NUMERIC_COLUMN > 0 then 1
else 0
end IS_POSITIVE,
(select sign(COUNT(*))
from SOME_OTHER_TABLE
where parent_id = T.ID) HAS_CHILDREN
...
from SOME_TABLE T
Design these expression in such a way that you get 1 when a condition is met and 0 when it's not.
Then sum up the score and add a WHERE clause.
SELECT *
FROM (
SELECT R.*,
IS_POSITIVE + HAS_CHILDREN + ... SCORE
FROM (...) R)
WHERE SCORE > 2
Of course you're gonna pay a hefty price in performance for this. You won't be able to use your conditions directly to limit the resultset so I'd expect the execution plans to be extremely disappointing. That said, it's not like what you have in mind is a standard task for RDBMS so it should be enough for a proof of concept.
Suppose I have a table :
start_range end_range
1 4
4 8
I want the result to be true if it is greater than any of the value of start_range and less than any of the corresponding end_range.
Eg.
value 2 should return true , as 2>1 and 2<4
but value 4 should return false in this case as 4>1 but 4<4 becomes false, as well as 4>4 becomes false for the second case.
I cannot use the query
SELECT Sumthing
FROM XYZ
WHERE value> SOME(start_range) AND value < SOME(end_range)
The problem with the above query is let say value = 4.
Now 4> SOME(start_range) will become true as 4>1. AND
4< SOME(end_range) will also become true as 4<8.
But in actual the comparison should be like (((4>1)AND(4<4)) OR ((4>4)AND(4<8))) . It should return false.
One more thing , the above table is not persistent , I have been creating it in a subquery.Thats why i have been using SOME.
if still my question isn't clear, mention in comments.
Assuming that xyz is your table:
select (count(*) > 0) as HasMatch
from xyz
where value > start_range and value < end_range;
I'm not sure why you are using some.
EDIT:
It occurs to me that you want to use subqueries, and xyz is not the table in question. Perhaps this is what you want:
select xyz.*
from xyz
where exists (select 1
from (<your query here>) t
where xyz.value > t.start_range and xyz.value < t.end_range
);
you can do something like this
SELECT CASE WHEN start_range<value and end_range>value
THEN 'true'
ELSE 'false'
END here_name_to_this_column(optional)
FROM table_name
tutorial link
select (count(*) > 0) as HasMatch
from (select IF(start_range<value and end_range>value, true, false ) as value
from XYZ having value =1) as MatchTable
DEMO
I am trying to update my table like this:
Update MyTable
SET value = 1
WHERE game_id = 1,
x =-4,
y = 8
SET value = 2
WHERE game_id = 1,
x =-3,
y = 7
SET value = 3
WHERE game_id = 2,
x = 5,
y = 2
I can do a foreach() but that will send over 50 separate Queries which is very slow.
That's why I want it to be combined into 1 big Query.
( I do use an id for each row but the combination of game_id, x and y is what I use to Identify the row I need. )
The update_batch() function from codeIgniter described here:
Update batch with CodeIgniter
was helpful and almost perfect but it only allows for 1 single where clause, you cannot (as far as I understood and tried) enter an array with multiple where clauses.
I've also checked out this question:
MYSQL UPDATE SET on the Same Column but with multiple WHERE Clauses
But it only allows for multiple row updates containing only a single different WHERE clause and I need multiple WHERE clauses! :)
Anwsers can be in simple SQL or with the use of php (and CodeIgniter) or in a different way. I'd this problem to be solved in any possible way ;)
I can really use the advice/help! =D
give this a try by using CASE
Update MyTable
SET value = CASE
WHEN game_id = 1 AND x = -4 AND y = 8 THEN 1
WHEN game_id = 1 AND x = -3 AND y = 7 THEN 2
WHEN game_id = 2 AND x = 5 AND y = 2 THEN 3
ELSE value
END
WHERE game_ID IN (1,2,3) AND -- the purpose of this WHERE clause
x IN (-4, -3, 5) AND -- is to optimize the query by preventing from
y IN (8,7,2) -- performing full table scan.
I need to update a MYSQL Table
Here is a very simple look at Table_A
ID VALUE RESULT
1 4 0
2 2 0
3 7 0
I want to update the RESULT Column based on conditions
So my query statement needs to look something like
UPDATE Tabel_A
SET RESULT = (if some condition) 1
OR (if another condition) 2
OR (if a different condition) 3
Or should I use something like
UPDATE Tabel_A
SET RESULT = (CASE 1) 1
(CASE 2) 2
(CASE 3) 3
I am not sure how to structure the query
Thanks
I'll prefer to use CASE here.
UPDATE TAble1
SET Result = CASE value
WHEN 1 THEN x
WHEN 2 THEN y
....
ELSE z
END
or
UPDATE TAble1
SET Result = CASE
WHEN value = 1 THEN x
WHEN value = 2 THEN y
....
ELSE z
END