Update MySQL with if condition - mysql

It seems I have big problems with conditional queries.
I have to do a conditional update. I write here what I would like to do:
IF(SELECT tipo FROM abbonamento WHERE idU = 17) = 'punti' THEN
UDPATE abbonamento SET punti = punti - 1
ELSE
UPDATE abbonamento SET bonus = bonus - 1
Obviously this doesn't work.
Any idea?

MySQL supports IF statement.
UPDATE abbonamento
SET punti = IF(tipo = 'punti', punti - 1, punti),
bonus = IF(tipo <> 'punti', bonus - 1, bonus)
WHERE id = 17
or you can also use CASE
UPDATE abbonamento
SET punti = CASE WHEN tipo = 'punti' THEN punti - 1 ELSE punti END,
bonus = CASE WHEN tipo <> 'punti' THEN bonus - 1 ELSE bonus END
WHERE id = 17

Related

SQL: return the select value in the stored procedure

I have stored procedure with 3 statements to update sta_fk_col_id in the status table. For test porpuses, I want to return the value in sta_fk_col_id without updating the table. Instead of UPDATE status SET sta_fk_col_id = I tried to do something like SET valido = but without seccuss.
SET valido
CREATE DEFINER=`tpcroot`#`%` PROCEDURE `sp_test_store_procedure`(IN functionId INT, out valido int)
BEGIN
-- statement 1.1
SET valido =
(SELECT CASE WHEN MAX(mon_alertlevel) >= 60 THEN 3 WHEN MAX(mon_alertlevel) < 60
AND MAX(mon_alertlevel) >= 30 THEN 2 ELSE 1 END AS color
FROM monitor INNER JOIN monitor_system ON fk_mon_id = mon_funct_id
WHERE fk_dri_id IN (110))
WHERE sta_fk_dri_id = (110);
-- statement 1.2
SET valido =
(SELECT color FROM ( SELECT MAX(sta_fk_col_id) AS color FROM status WHERE sta_fk_mty_id = 1
AND sta_fk_sys_id = 4
AND sta_fk_dri_id IS NOT NULL) helptable)
WHERE sta_fk_sys_id = 4 AND
sta_fk_mty_id = 1 AND sta_fk_dri_id IS NULL;
-- statement 2
SET valido = (SELECT CASE WHEN MAX(mon_alertlevel) >= 60 THEN 3 WHEN MAX(mon_alertlevel) <60 AND MAX(mon_alertlevel) >= 30 THEN 2 ELSE 1 END AS color
FROM monitor_system INNER JOIN monitor ON fk_mon_id = mon_funct_id AND mon_funct_id = functionId)
WHERE sta_fk_mty_id = 1 AND
sta_fk_sys_id = 4 AND
sta_fk_dri_id IS NULL AND
(SELECT countDrilldown FROM (select Count(*) AS countDrilldown FROM status
WHERE sta_fk_mty_id = 1 AND
sta_fk_sys_id = 4 AND sta_fk_dri_id IS NOT NULL) helptable) = 0;
select #valido;
END
I am calling the stored procedure like this:
CALL sp_test_store_procedure(2315, #returnValue);
select #returnValue;

if statement mySQL

I am trying to figure out how to do an if statement that will essentially calculate the stock of an item based on the dates in the tp_rental table.
I was hoping to do something like :
if Date_Due has an entry but Date_Returned does not
then set stock -1
if Date_Due has an entry and Date_returned has an entry entered
then set stock +1
See below for my attempt, not sure if i need a join here?
update title_platform
set Stock = case
when tp_rental.Date_Returned is not null then stock -1
else stock +1
end
Am I going about this the right way?
You need an UPDATE statement with a join between the 2 tables and a CASE expression:
update title_platform p inner join tp_rental r
on r.platformid = p.platformid
set p.stock = p.stock + case
when r.date_due is not null and r.date_returned is null then -1
when r.date_due is not null and r.date_returned is not null then 1
else ? -- if there is another option
end
Remove the else part if it is not needed.
Edit: if there are multiple rows in tp_rental for each platformid then you must aggregate first and then join:
update title_platform p inner join (
select platformid,
sum(date_due is not null and date_returned is not null) -
sum(date_due is not null and date_returned is null) result
from tp_rental
group by platformid
) r on r.platformid = p.platformid
set p.stock = case
when p.stock + r.result < 0 then 0
else p.stock + r.result
end

MySQL Case in Update

I've browsed the forums. I've tested several different methods. I just can't get this to work.
GOAL:
Update the next column if an answer exists in the previous column
Q1 IS NULL at this point and I want it set to 1
Q2 IS NULL and I want it to stay NULL if Q1 IS NULL, If Q1 has an answer, update this column to 1
PROBLEM:
Both columns always update to 1
ATTEMPTS:
UPDATE Story1_Responses
SET Q1 = IFNULL(Q1,'1'),
Q2 = CASE WHEN Q1 IS NULL THEN NULL ELSE '1' END
WHERE UserID = 16
UPDATE Story1_Responses
SET Q1 = IFNULL(Q1,'1'),
Q2 = CASE WHEN IFNULL(Q1,'') = '' THEN NULL ELSE '1' END
WHERE UserID = 16
UPDATE Story1_Responses
SET Q1 = IFNULL(Q1,'1'),
Q2 = CASE WHEN COALESCE(Q1, '') = '' THEN NULL ELSE '1' END
WHERE UserID = 16
UPDATE Story1_Responses
SET Q1 = IFNULL(Q1,'1'),
Q2 = CASE WHEN Q1 IS NOT NULL THEN '1' ELSE IFNULL(Q2,NULL) END
WHERE UserID = 16
THOUGHTS:
It seems to me that MySQL updates the first column prior to the second column being evaluated even though they are in the same update statement execution.
Order is important. First set Q2 (because it checks the previous value of Q1), then set Q1.
UPDATE Story1_Responses
SET Q2 = CASE WHEN Q1 IS NULL THEN NULL ELSE '1' END,
Q1 = IFNULL(Q1,'1')
WHERE UserID = 16;
SQLFiddle

Query using CASE WHEN

I am trying to write a query like this and I am getting an error. It is my first time using case, so that's where I believe the problem to be.
UPDATE my_table
CASE
WHEN downloads IS NULL THEN
SET downloads = 1
ELSE
SET downloads + 1
END
WHERE attachment_id = 8990
AND parent_post_id = 9221
OR attachment_id = 9211
AND parent_post_id = 383
You can rewrite it as below
UPDATE my_table
SET downloads = CASE WHEN downloads IS NULL THEN 1
ELSE downloads + 1 END
WHERE attachment_id = 8990
AND (parent_post_id = 9221
OR attachment_id = 9211 )
AND parent_post_id = 383
Also you need to group your or condition in () in order to match 9211 against parent_post_id and attachment_id with or operation,also there is confusing conditions you have in your query how parent_post_id and attachment_id can be equal to 2 values at same time may be you are looking for
WHERE (attachment_id = 8990 AND parent_post_id = 9221 )
OR (attachment_id = 9211 AND parent_post_id = 383)
updates syntax is update table set col=value where condition. Using case doesn't change that. case can only be used to return an expression, so:
UPDATE my_table
SET downloads = CASE WHEN downloads IS NULL THEN 1 ELSE downloads + 1 END
WHERE attachment_id = 8990 AND
parent_post_id = 9221 OR
attachment_id = 9211 AND
parent_post_id = 383

MySQL transaction with 1 update statement takes >4s in a 4000 row table

Most of the time this transaction takes <1s, average of 200ms or so. But occasionally, it takes >4s! This sproc gets run 5-6 times per second or so.
My sproc is pretty simple (innoDB - REPEATABLE READ):
START TRANSACTION;
SELECT end_time INTO currentEndTime FROM auctions WHERE id=var_auction_id;
IF (ADDTIME(currentEndTime , var_time_increment) < NOW()) THEN
UPDATE auctions SET end_time = ADDTIME(NOW(), var_time_increment), price = price+var_price_increment, leader_id = var_leader_id, modified = NOW() WHERE id = var_auction_id AND closed = 0;
ELSE
UPDATE auctions SET end_time = ADDTIME(end_time, var_time_increment), price = price+var_price_increment, leader_id = var_leader_id, modified = NOW() WHERE id = var_auction_id AND closed = 0;
END IF;
SELECT ROW_COUNT() INTO myRowCount;
IF (_error) THEN
ROLLBACK;
ELSE
SET var_return = myRowCount;
COMMIT;
END IF;
I want to figure out what's causing the 4s spikes, things I have tried:
I thought it might be concurrent, but I've seen this sproc called 5 times in 1 second, and those transactions take <100ms. And for the 4s ones, it's not that many concurrent transactions
Index is set properly on id
Table is small... 4000 rows or so.
Can't really run slow query log since it's MySQL 5.0, want to avoid rebooting the server to turn on the slow query flag unless it's the last resort.
I need some suggestions on the cause or what else to investigate.
Not sure if this will help but these lines:
SELECT end_time INTO currentEndTime FROM auctions WHERE id = var_auction_id;
IF (ADDTIME(currentEndTime, var_time_increment) < NOW()) THEN
UPDATE auctions
SET end_time = ADDTIME(NOW(), var_time_increment)
, price = price + var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
ELSE
UPDATE auctions
SET end_time = ADDTIME(end_time, var_time_increment)
, price = price+var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
END IF;
can be rewritten as:
UPDATE auctions
SET end_time
= ADDTIME( CASE WHEN ADDTIME(end_time, var_time_increment) < NOW()
THEN NOW()
ELSE end_time
END
, var_time_increment
)
, price = price + var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
or:
UPDATE auctions
SET end_time
= ADDTIME( CASE WHEN end_time < ADDTIME(NOW(), - var_time_increment)
THEN NOW()
ELSE end_time
END
, var_time_increment
)
, price = price + var_price_increment
, leader_id = var_leader_id
, modified = NOW()
WHERE id = var_auction_id
AND closed = 0;
A compound index on (closed, id) should also help the UPDATE statement to avoid reading from the table when closed <> 0.