How to 2 UPDATE in One MySQL Query - mysql

in MySQL query
How to do 2 UPDATE in one Query, the query below:
UPDATE `stats` SET `coin` = coin + 500 WHERE `player` = 'userone'
UPDATE `stats` SET `coin` = coin - 500 WHERE `player` = 'usertwo'

You can use case and in:
UPDATE `stats`
SET `coin` = coin + (case when player = 'userone' then 500 else -500 end)
WHERE `player` in ( 'userone', 'usertwo');

UPDATE stats
SET coin = CASE player
WHEN 'userone' THEN coin + 500
WHEN 'usertwo' THEN coin - 500
END
WHERE player IN ('userone', 'usertwo')

Related

Unable to limit

I have the following query:
UPDATE pc
INNER JOIN cams
ON cams.cam_id = pc.camuid
SET
timestamp = NOW(),
uid = #out_param:=uid
WHERE zone = 1
AND (unable = '0' OR unable IS NULL)
AND (corrected_plate = '' OR corrected_plate IS NULL)
AND (timestamp IS NULL OR timestamp < (NOW() - INTERVAL #interval MINUTE))
LIMIT 1;
SELECT #out_param;
I am unable to run that query as I have a LIMITclause in a join query. I cannot figure out how to spread it out into a subquery while maintaining performance. I need this query to be as fast as possible, and the optimiser of MySQL has not provided much help so far.
This is the error obtained from MySQL, as the above is not allowed: Incorrect usage of UPDATE and LIMIT
Just use a subquery to decide which uid update.
UPDATE PC
SET timestamp = NOW(),
uid = #out_param:=uid
WHERE uid = (SELECT uid
FROM ( SELECT * FROM pc ) as pc2
INNER JOIN cams
ON cams.cam_id = pc2.camuid
WHERE zone = 1
AND (unable = '0' OR unable IS NULL)
AND (corrected_plate = '' OR corrected_plate IS NULL)
AND (timestamp IS NULL OR timestamp < (NOW() - INTERVAL #interval MINUTE))
ORDER BY uid -- optional
LIMIT 1)

mySQL update next 12 NULL values with date increment by 1

Basically, I have these 2 queries:
SELECT * FROM table
WHERE langue = 'fr' AND hDate IS NULL
LIMIT 12;
UPDATE table
SET hDate = CURDATE() + INTERVAL 1 DAY
WHERE hDate IS NULL
LIMIT 12;
These works good for first 12 NULL records. If I need to update next 12 NULL records I have to manually change the UPDATE query to INTERVAL 2 DAY
Problem is that I have 4000 records.
I have tried
UPDATE table t1 JOIN
(
SELECT id, #n := #n + 1 rnum
FROM table CROSS JOIN (SELECT #n := 0) i
WHERE langue = 'fr'
ORDER BY id
) t2 ON t1.id = t2.id CROSS JOIN
(
SELECT MAX(hDate) sdate FROM table
) q
SET t1.hDate = q.sdate + INTERVAL t2.rnum DAY
from this answer: MySQL query to update records with incremented date
but this increments each record with 1 day. I have to increment 12 records with same date, next 12 records with date + 1, next 12 records with date + 2 etc.
Table definition
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`texte` mediumtext,
`langue` varchar(9) DEFAULT NULL,
`hDate` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6726 DEFAULT CHARSET=utf8;
Thanks for your help.
http://sqlfiddle.com/#!9/7a554/1
SET #i:=0;
SET #j:=0;
UPDATE t1
RIGHT JOIN (
SELECT
id
,IF(#j = 0 ,#j:=1, #j:=#j+1)
,IF((#j-1) % 12 = 0, #i:= #i+1, #i) as i
FROM t1
WHERE hDate IS NULL
) idx
on idx.id = t1.id
SET t1.hDate = CURDATE() + INTERVAL (idx.i) DAY

I want to check the value of subquery how to check it?

This is my update query in mysql
UPDATE userentries
SET User_Rank =
(
SELECT
urc.rankofentr as User_Rank
from UserRankingsys as urc
WHERE urc.entryid = userentries.id
LIMIT 1
)
where userentries.id = 15
I want to check the value which is returned by that section
(
SELECT
urc.rankofentr as User_Rank
from UserRankingsys as urc
WHERE urc.entryid = userentries.id
LIMIT 1
)
how i can do this if this sub query returns greater than 20 than i want to set the value 102
You can use CASE
SELECT case urc.rankofentr when > 20 then 20
else urc.rankofentr
end as User_Rank
from UserRankingsys as urc
WHERE urc.entryid = userentries.id
LIMIT 1
for you sql
UPDATE userentries
SET User_Rank =
(
SELECT case urc.rankofentr when > 20 then 20
else urc.rankofentr
end as User_Rank
from UserRankingsys as urc
WHERE urc.entryid = userentries.id
LIMIT 1
)
where userentries.id = 15;

Mysql: update to create group of visit entries separated by no more than maxmium minutes

I have the following mysql table which records user visit times:
I'd like to update visit_id so that a "visit" is a group of entries for the same user where no entry is more than 20 minutes after the previous, and the visit_id for each entry is the visit_id of the first entry of that visit.
I hope that this example helps make it clear. After the update, the example table above should become:
I'm able to create an update which sets the visit_id to the visit_id of the previous entry for that user if the previous entry occurred less than 20 minutes before.
But I can't solve how to create a sql-only update to deal with the "cascading" effect, in other words, that the visit_id needs to find the earliest entry for that user_id which occurs before a 20-minute gap. It might be the visit_id of that entry (if it's the first of that visit), or the visit_id of previous entry, or of the previous-previous, or of the previous-previous-previous-previous, etc.
How could I write this update?
Try this query (but don't try it on production data, but rather on a copy of this data):
update tabb_after_update tabb,
(
select t.*,
( SELECT min( visit_id )
FROM tabb_after_update t1
WHERE t1.user_id = t.user_id
AND t1.time_of_visit <= t.time_of_visit
AND t1.time_of_visit >= subtime( t.time_of_visit, '00:20' )
) new_id
from tabb_after_update t
) tabb1
SET tabb.visit_id = tabb1.new_id
WHERE tabb.user_id = tabb1.user_id
AND tabb.visit_id = tabb1.visit_id
;
SQLFiddle demo --> http://www.sqlfiddle.com/#!2/caa08/1
------ EDIT -----
Another version that "joins gaps" into one group if gaps are <= 20 minutes.
set #last_uid = 0;
set #last_tm = '00:00';
set #last_vid = 0;
update tabb_after_update tabb,
(
select t.* ,
case when #last_uid = user_id
AND cast( #last_tm as time) >= subtime( time_of_visit, '00:20' )
then if( (#last_tm := time_of_visit ), #last_vid, #last_vid )
else
if( (#last_uid := user_id) +
(#last_vid := visit_id ) +
(#last_tm := time_of_visit ),
#last_vid, #last_vid )
end new_id
from tabb_after_update t
order by user_id, time_of_visit
) tabb1
SET tabb.visit_id = tabb1.new_id
WHERE tabb.user_id = tabb1.user_id
AND tabb.visit_id = tabb1.visit_id
;
SQLFiddle demo --> http://www.sqlfiddle.com/#!9/39f03/1
In this demo the user 1 has entries from 17:10 to 17:50 with "gaps" betwen records less than 20 minutes, and the query "combines" all these records into one group.

Update multiple rows from same table in mysql

Update a single column over multiple rows depending on the data from the same table.
update table1 set status=newtime
from (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
where id2='2'
and status='0'
)
where id=new_id
This is my query. Thanks in advance.
Edit:
This is an alternate query to achieve this. But it also gives me an error
update table1 set status=
(select
case when timeleft<0 then '4' else '0' end as something,
new_id
from
(
select
TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss') as newtime,
id as new_id
FROM
table1
where id2='2' and
status='0'
)
}
where id=new_id
"#1248 - Every derived table must have its own alias".
I cannot use alias as I am fetching two columns from the query. Any help would be great.
UPDATE statements have no FROM clause in MySQL syntax. However, you can JOIN table against the subquery.
UPDATE
table1 t1
JOIN (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
WHERE id2='2' AND status='0'
) tsub ON t1.id = tsub.new_id
SET status = tsub.newtime
It looks to me like you don't need to do any subquerying or joining at all. This should do what you want:
UPDATE table1
SET status = CASE WHEN TIME_FORMAT(TIMEDIFF(ADDTIME(time_val, '120:00:00'), NOW()), '%Hh %im %ss') < 0 THEN '4' ELSE '0' END
WHERE id2 = '2' AND status = '0'
In the query you wrote, your subquery will get back the new time_val and the id number of the row to update, for any rows that match the criteria id2 = '2' AND status = '0'. You will then update all those rows (that matched the above criteria) and set the status to the new time_val.
Instead of selecting them first, cut out the middle man and just update all rows that match that criteria with the new value. Your query will be faster and more straightforward.
Besides the simplified version (provided by #Travesty3), it seems you are using a whole bunch of date and time functions to test for a simple thing:
UPDATE table1
SET status = '4'
WHERE id2 = '2'
AND status = '0'
AND time_val < NOW() - INTERVAL 120 HOUR
We can update table with multiple row by same table or two different table in this manner, just posting a snippet of mysql code from my procedure
Update documentcolumns as tb1, documentcolumns as tb2 set tb1.documentColumnPos = tb2.documentColumnPos Where tb1.userID = user_id and tb2.userID is NULL and tb1.columnNameDefID= tb2.columnNameDefID and tb1.tabtype = tab_type and tb2.tabtype = tab_type;,