I've following sql to update results table:
$mysqli->query("UPDATE results
SET result_value = IF('$logo_value' - result_tries < 0 OR '$logo_value' - result_tries = 0, 1, '$logo_value' - result_tries)
WHERE logo_id = '$logo_id'
AND user_id = '$user_id'
AND result_value = 0");
In the same sql command is it possible to update another table based on result_value?
if result_value = 10
Update users SET user_hints = user_hints +1 WHERE user_id = '$user_id'
How would I incorporate this into sql syntax above?
Long way I can think of is to select this value get it into php variable. And than do another update based on php variable value... But this seems long and tedious
This is a long shot (not tested) but how about:
$mysqli->query("UPDATE results, users
SET result_value =
IF('$logo_value' - results.result_tries < 0 OR
'$logo_value' - results.result_tries = 0,
1, '$logo_value' - result_tries),
users.user_hints =
IF(results.result_value >= 10,
users.user_hints + 1, users.user_hints)
WHERE results.logo_id = '$logo_id'
AND results.user_id = '$user_id'
AND results.user_id = users.user_id
AND results.result_value = 0");
If both tables have some of the same column names, of course, youll have to specify which table (like results.user_id -or- users.user_id)
Related
I have a system that collects data from production reports (CSV files) and puts them into a mySql DB.
I have an header table, that contain the production data of sequential report with same setting, and a table with the single reports, connected to the first one (trfCamRep.hdrId -> trfCamHdr.id).
I have a query to calculate the total report, the dubt and the faulty, and the maxTs. These datas are used in the visualizator.
The query is too slow, it requires 9sec.
Can you help me to speed up it?
SET #maxId:=(SELECT MAX(id) FROM trfCamHdr WHERE srcCod='7');
UPDATE trfCamHdr AS hdr
LEFT JOIN (SELECT hdrF.id,COUNT(*) AS nTot,
SUM(IF(res=1,1,0)) AS nWrn,SUM(IF(res=2,1,0)) AS nKO,
MAX(ts) AS maxTS
FROM trfCamHdr AS hdrF
JOIN trfCamRep AS repF ON repF.hdrId=hdrF.id
WHERE clcEnd=0 AND srcCod='7'
GROUP BY hdrF.id) AS valT ON valT.id=hdr.id
SET hdr.clcEnd=IF(hdr.id<#maxId,1,0),
hdr.nTot=valT.nTot,
hdr.nWrn=valT.nWrn,
hdr.nKO=valT.nKO,
hdr.maxTS=valT.maxTS
WHERE hdr.id>=0 AND hdr.clcEnd=0 AND hdr.srcCod='7';
Note trfCamHdr has these columns:
id (primary key)
clcEnd : flag of end calculation (the last remain to 0 because in progress)
nTot : elements with this header
nWrn : elements with res = 1
nKO : elements with res = 2
maxTs : TS of the last element
trfCamRep has these columns:
hdrId (refer to id of trfCamHdr)
res : 0 good, 1 dubt, 2 fault
ts : report timestamp
I'd take this out:
SET #maxId:=(SELECT MAX(id) FROM trfCamHdr WHERE srcCod='7');
And any allusions to the MaxId variable, I believe it to be redundant.
Everything you do will be lower than the max id, and it will take time to calculate if its a big table. You are already checking for srcCod = 7, so it isn't necessary.
In fact, it would miss the update on the one with the actual max id, which is not what I believe you want.
Your left join will also update all other rows in the table with NULL, is that what you want? You could switch that to an inner join, and if your rows are already null, they will just get left alone, rather than getting updated with NULL again.
Then you could just switch out this:
SET
hdr.clcEnd = IF(hdr.id < #maxId, 1, 0),
To
SET
hdr.clcEnd = 1,
Here is the rewritten thing, as always, back your data up before trying:
UPDATE trfCamHdr AS hdr
INNER JOIN
(SELECT
hdrF.id,
COUNT(*) AS nTot,
SUM(IF(res = 1, 1, 0)) AS nWrn,
SUM(IF(res = 2, 1, 0)) AS nKO,
MAX(ts) AS maxTS
FROM
trfCamHdr AS hdrF
JOIN trfCamRep AS repF ON repF.hdrId = hdrF.id
WHERE
clcEnd = 0 AND srcCod = '7'
GROUP BY hdrF.id) AS valT ON valT.id = hdr.id
SET
hdr.clcEnd = 1,
hdr.nTot = valT.nTot,
hdr.nWrn = valT.nWrn,
hdr.nKO = valT.nKO,
hdr.maxTS = valT.maxTS
WHERE
hdr.id >= 0 AND hdr.clcEnd = 0
AND hdr.srcCod = '7';
I found the solution: I created a KEY on hdrId column and now the query requires 0.062s.
So, I am trying to update the status_modified_time only if the status has changed, else keep it the same.
UPDATE table SET status = <new_status>,
status_modified_time = IF(status = <new_status>, status_modified_time, now()) WHERE id = <id>
this query makes status_modified_time = status_modified_time
UPDATE table SET status = <new_status>,
status_modified_time = IF(status = <old_status>, status_modified_time, now()) WHERE id = <id>
this query makes status_modified_time = now()
is it that mysql is updating the status field first and then checking the condition??
Left to right order of evaluation!
SQL UPDATE order of evaluation
I checked my query by updating the modified_time first.
I've got two Queries to Update two tables:
First Table
UPDATE user_info SET `location` = ".$locationid.", `looking_for` = ".$lookingfor." WHERE `user_info`.`user_id` = ".$infoid.";
Second Table
UPDATE user_personality SET `personality` = '".$changedescription."' WHERE `user_personality`.`user_info_id` = ".$infoid.";
And I'm trying to merge those two Queries, using the same statement.
UPDATE user_info, user_personality
SET user_info.location = ".$locationid.", user_info.`looking_for` = ".$lookingfor.", user_personality.personality = '".$changedescription."'
WHERE `user_info`.`user_id` = ".$infoid."
AND `user_personality`.`user_info_id` = ".$infoid."
I'm not receiving any error message, but is not updating.
What am I doing wrong?
Thanks.
Just a guess...
"
UPDATE user_info i
JOIN user_personality p
ON p.user_info_id = i.user_id
SET i.location = $locationid
, i.looking_for = '$lookingfor'
, p.personality = '$changedescription'
WHERE i.user_id = $infoid;
";
If you set the 2 table fields equal to each other in the where clause it should work, so I believe you'd change your where clause to:
WHERE `user_info`.`user_id` = `user_personality`.`user_info_id`
AND `user_info`.`user_id` = ".$infoid."
MySQL definitely supports updating multiple tables, so the where clause that works for a multi table select statement should also work for an update.
I want to compare real results and predictions from 2 similar tables on mysql.
real
id | data1| data2 |
user
id | data1| data2 | points
ranking
id | user| total points
I want to do the following:
if (real.data1 = user.data1) AND (real.data2 = user.data2)
update user set points=8 where id=1
else if(real.data1 > user.data1) AND (real.data2 > user.data2)
update user set points=4 where id=1
else if (real.data1 = real.data2) AND (user.data1 = user.data2)
update user set points=4 where id=1
else if (real.data1 < user.data1) AND (real.data2 < user.data2)
update user set points=4 where id=1
else
update user set points=0 where id=1
sum all values from points and update ranking table
Is it possible?
I believe the below will work for the first half of your question, but I have not tested it:
UPDATE `user` u
INNER JOIN `real` r ON (u.id = r.id)
SET u.points = IF(r.data1 = u.data1 and r.data2 = u.data2,
8,
IF(r.data1 > u.data1 and r.data2 > u.data2,
4,
IF(r.data1 = r.data2 and u.data1 = u.data2,
4,
IF(r.data1 < u.data1 and r.data2 < u.data2,
4,
0)
)
)
)
See the MySQL docs concerning the IF statement if this doesn't make sense.
I try to change my code from MYSQL to SQL and i got an error (SQL Syntax 'Limit').
So i tried to change my query and update with "TOP" but seems to work only with SELECT.
So, how can i change this MYSQL query :
$fct="UPDATE `users` SET `STREAM_TITRE` = '$STREAM_TITRE',`STREAM_URL` = '$STREAM_URL',`STREAM_DESC` = '$STREAM_DESC',`STREAM_GENRE` = '$STREAM_GENRE' WHERE `ID` =$IDSESS LIMIT 1";
Here is my SQL Code without Limit :
$fct="UPDATE users SET STREAM_TITRE = '$STREAM_TITRE', STREAM_URL = '$STREAM_URL', STREAM_DESC = '$STREAM_DESC', STREAM_GENRE = '$STREAM_GENRE' WHERE ID = '$IDSESS'";
Thanks
It's not very clear which version of your query is working and which is not - and in what DBMS.
If ID is of char or varchar type, you are missing some quotes in the LIMIT version. Although MySQL is not very picky and you won't have many issues, with or without quotes:
$fct = "
UPDATE users
SET STREAM_TITRE = '$STREAM_TITRE'
, STREAM_URL = '$STREAM_URL'
, STREAM_DESC = '$STREAM_DESC'
, STREAM_GENRE = '$STREAM_GENRE'
WHERE ID = $IDSESS --<-- this should be '$IDSESS' , right?
----- or $IDSESS , depending on the datatype
LIMIT 1
";
Note: The LIMIT n works in MySQL and PostgreSQL, but not in some other DBMS. Plus, I don't think you really need it anyway, as the ID is probably the Primary Key of the table.
If you are trying to convert the statement from MySQL to SQL-Server, you should not use the backquotes and replace LIMIT 1 with TOP (1):
$fct = "
UPDATE TOP (1) users
SET STREAM_TITRE = '$STREAM_TITRE'
, STREAM_URL = '$STREAM_URL'
, STREAM_DESC = '$STREAM_DESC'
, STREAM_GENRE = '$STREAM_GENRE'
WHERE ID = $IDSESS
";