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.
Related
enter image description here
I have table with these datas, after do some operations I want to update flag value from 0 to 1 based on the two columns value code and id
update table set flag = 1 where code = 'ABC' and id = 10000
update table set flag = 1 where code = 'DEF' and id = 10001
update table set flag = 1 where code = 'GHI' and id = 10002
update table set flag = 1 where code = 'ABC' and id = 10001
I can do like this with foreach But I want to update using single query
How can I achieve this?
this should work
UPDATE table SET flat = 1 WHERE (code = 'ABC' and id = 10000) OR (code = 'DEF' and id = 10001) OR (code = 'GHI' and id = 10002)
I'm trying to code a monopoly game and I'm getting a syntax error for the following:
SET #Token = 'Thimble';
SET #Roll = 7;
UPDATE Players
SET Players.Jail = FALSE, #Roll = #Roll - 6
WHERE Players.Jail = TRUE AND Players.Token = #Token AND #Roll > 5;
Is it not possible to set the value of a temp variable as part of UPDATE? I need #roll and Players.Jail to only update if the WHERE condition is met, so I can't see a way of updating them separately.
No, you can't SET #Roll in an UPDATE statement. You can only SET a column.
It's not a good practice to use tricks with temp variables like you are trying to do, because the order of evaluation of the variables is not well defined.
In this case, you should just do this:
UPDATE Players
SET Players.Jail = FALSE
WHERE Players.Jail = TRUE AND Players.Token = #Token
ORDER BY ...something...
LIMIT 1;
Using LIMIT doesn't make much sense without an ORDER BY, but I can't tell from your example which order you want to update the rows.
With updates you can't do this directly
You could solve this with help of a further , you update the valuen to #Roll and set so the new value
CREAte tablE Players (Jail INT , token varchar(10))
INSERT INTO Players VALUES (1,'Thimble')
CREATE TABLE Rolls(Roll int);
INSERT INTO Rolls VALUES(7)
SET #Token = 'Thimble';
SET #Roll = 7;
UPDATE Players,Rolls
SET Players.Jail = FALSE, Rolls.Roll = #Roll - 6
WHERE Players.Jail = TRUE AND Players.Token = #Token AND #Roll > 5
SET #Roll := (SELECT Roll FROM Rolls ORDER BY 1 LIMIT 1)
SELECT #Roll
| #Roll |
| ----: |
| 1 |
SELECT * FROM Players
Jail | token
---: | :------
0 | Thimble
db<>fiddle here
I have many tables with the same structure for each of my costumers.
All information are distinct for each table.
For some reason, I need to create some temporary table with the same structure with 200 values everytime I run.
So let's assume I have 3 tables.
Costumer1, Costumer2, Costumer3.
All those tables have id, user_name, contact_name, contact_email, sent1, sent2, sent3, sent4, status.
I need some query to put inside costumer_tmp, only 200 values in total, from all those 3 tables, everytime I run the script. And everytime I run cant repeat the last values I got before.
So for example:
Costumer1
id = 29
user_name = test1
contact_name = contact1
contact_email = contact1#mail.com
sent1 = yes
sent2 = no
sent3 = no
sent4 = no
status = In Progress
Costumer2
id = 37
user_name = test2
contact_name = contact123
contact_email = contact123#mail.com
sent1 = yes
sent2 = no
sent3 = no
sent4 = no
status = In Progress
Costumer3
id = 87
user_name = test3
contact_name = contact231
contact_email = contact231#mail.com
sent1 = yes
sent2 = no
sent3 = no
sent4 = no
status = In Progress
How to Insert on costumer_tmp only 2 records of those 3 and next time I run the script don't repeat those 2 records, just insert only 1 record remaining.
Your requirement is a bit weird, but if I understand weel, how about something like : (not tested)
insert into costumer_tmp
select * from Costumer1 one where one.id not in (select id from costumer_tmp)
union all
select * from Costumer2 two where two.id not in (select id from costumer_tmp)
union all
select * from Costumer3 three where three.id not in (select id from costumer_tmp) LIMIT 200
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.
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)