I have a table in MySQL that looks like this:
studentID subjectID anotherID anotherID2, AnotherID3, studentScore
This table has about 100M records of students in it.
Suppose that I have the following information stored in two python lists:
listStudentIDs = [1, 123, 33, 5524, 425653]
listNewScores = [12.76, 73.2, 83.893, 92.3, 53.6]
Is it possible to have one query that will update all studentScore fields for all students (whose IDs are in listStudentIDs) if, and only if, their score in listNewScores is greater than their score currently stored in the database ( studentScore )?
In your example, they are 5 student ids for only 4 scores to update.
If your list of students to update is not to long, then you can have an update in one query like this :
UPDATE t_student
SET studentScore = CASE
WHEN studentID=1 THEN 12.76
WHEN studentID=123 THEN 73.2
WHEN studentID=33 THEN 83.893
WHEN studentID=5524 THEN 92.3
ELSE studentScore END
WHERE studentID IN (1, 123, 33, 5524, 425653)
Nevertheless less you may consider to use a SQL statement including several queries :
UPDATE t_student SET studentScore = 12.76 WHERE studentID = 1;
UPDATE t_student SET studentScore = 73.2 WHERE studentID = 123;
UPDATE t_student SET studentScore = 83.893 WHERE studentID = 33;
UPDATE t_student SET studentScore = 92.3 WHERE studentID = 5524;
Unfortunately, no, MySql can't handle this. Otherwise, I'd be using it all the time!
Try putting your two lists into a temporary table (studentID, studentScore).
Then you should be able to run a single query to update the main table accordingly.
UPDATE studentTable t1
JOIN tempTable t2 ON t1.studentID = t2.studentID
SET t1.studentScore = t2.studentScore WHERE t2.studentScore > t1.studentScore
Related
I am trying to update multiple values at the same time,
Table values
UniqueRef, Name
1101, AA01
1102, AA02
1103, AA03
I want to update UniqueRef for all of 1101, 1102 and 1103 to different values e.g
1101 will be updated to 1101AB ect
how can I do this in bulk than one at a time?
Do it in a single UPDATE statement:
Seems like you need to update UniqueRef in a single pattern. So use following statement:
UPDATE YourTable SET name = CONCAT(UniqueRef, 'AB');
This will update all rows - in case you need to limit the scope use WHERE statement and define appropriate condition.
In case you need to use different values for each row use CASE statement in
UPDATE YourTable
SET name =
CASE
WHEN UniqueRef = 1101 THEN 'newValue'
WHEN UniqueRef = 1102 THEN 'anotherNewValue'
{nextStatements}
ELSE name
END
;
The scalable solution is to use UPDATE with a JOIN on a source for the new values (usually another table, but it can be an online view, such as below)
UPDATE
example
INNER JOIN
(
SELECT 1101 AS id, 'X' AS new_name
UNION ALL
SELECT 1102, 'Y'
)
AS update_map
ON update_map.id = example.uniqueRef
SET
example.name = update_map.new_name
Demo : https://dbfiddle.uk/g71hwuYG
I understand basically the concepts of UPDATE to use data in one table to update another similar table. However the table data I have to update to is arranged in a 'vertical' manner as opposed to the 'horizontal' manner of the input table. This query works if I limit it to just one record :
SELECT #userid:=user_id,#club:=CLUB, #financialdate:=FINANCIALDATE
FROM wpty_sa_tmp_update where user_id = 1;
UPDATE wpty_cimy_uef_data SET VALUE = #financialdate WHERE user_id = #userid and field_id = 16;
UPDATE wpty_cimy_uef_data SET VALUE = #club WHERE user_id = #userid and field_id = 8;
If I remove the WHERE user_id clause, it does not update .. what am I missing?
Obviously I can't create a join of any sort because the 2 tables don't share a common ID or key
cheers
You could actually do this from a single update statement:
UPDATE wpty_cimy_uef_data wc
INNER JOIN wpty_sa_tmp_update ws
ON wc.user_id = ws.user_id AND ws.user_id = 1
SET
VALUE = CASE field_id WHEN 16 THEN ws.FINANCIALDATE
WHEN 8 THEN ws.CLUB END
WHERE
field_id IN (8, 16);
I am new to SQL, I have a requirement where I have to increment the value in a specific column by 1 and update that value in the same column based on the id.
Here is what I want,
UPDATE books SET version_num =
(SELECT (version_num + 1) FROM books WHERE book_recid IN
('72b72282-707b-4dd4-ab08-f5a085e92a2b', '73255df2-413e-4aad-892d-edc08ffa3405'))
WHERE book_recid IN
('72b72282-707b-4dd4-ab08-f5a085e92a2b', '73255df2-413e-4aad-892d-edc08ffa3405');
I know the above query won't work. I want a query to update the values in the database like above.
It is simple to add 1 to a column.
You have just over complicated your query.
UPDATE books SET version_num = version_num +1
WHERE book_recid IN ('72b72282-707b-4dd4-ab08-f5a085e92a2b',
'73255df2-413e-4aad-892d-edc08ffa3405');
You can do a from in the update query
UPDATE A SET col1 = something
FROM B
INNER JOIN C on B.col4 = C.col5
WHERE A.col2 = B.col3
In your case, it could be something like the following
UPDATE books b SET version_num = tcp.version_num + 1
FROM tag_config_params tcp
WHERE tcp.book_recid = b.book_recid
AND tcp.book_recid IN ('72b72282-707b-4dd4-ab08-f5a085e92a2b', '73255df2-413e-4aad-892d-edc08ffa3405');
I'm assuming that book_recid is a foreign key relationship here.
Do like this
UPDATE books
SET version_num = tb1.vers
from (
SELECT (version_num + 1) as vers FROM tag_config_params
WHERE book_recid IN
('72b72282-707b-4dd4-ab08-f5a085e92a2b', '73255df2- 413e-4aad-892d-edc08ffa3405')
) tb1
WHERE book_recid IN
('72b72282-707b-4dd4-ab08-f5a085e92a2b', '73255df2-413e-4aad-892d-edc08ffa3405');
Is there a more efficient way of doing this? I do not want to update more than one record and it is possible that the two initial queries can match two different records.
SET #AppID = (SELECT appID FROM employees WHERE ssn = vSSN);
IF #AppID IS NULL THEN
SET #AppID = (SELECT appID from applications WHERE appDate = vDate);
END IF;
UPDATE applications
SET status = vStatus
WHERE appID = #AppID;
You can use the COALESCE operator and the UPDATE/REPLACE statement. To be more precise, COALESCE picks the first non-null value out of a comma-separated list.
http://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#function_coalesce
http://dev.mysql.com/doc/refman/5.5/en/update.html
http://dev.mysql.com/doc/refman/5.5/en/replace.html
First, the UPDATE alternative:
UPDATE applications AS app
INNER JOIN (
SELECT COALESCE(employees.appID, applications.appID) AS appID
FROM applications
LEFT OUTER JOIN employees
ON employees.ssn = vSSN
WHERE applications.appDate = vDate
-- do some ordering or filtering if the date is not unique
LIMIT 1) AS app2
ON app.appID = app2.appID
SET app.status = vStatus
Second, the REPLACE alternative. Please note that REPLACE first deletes the old entry and then reinserts the new one. Therefore, employees.appID may not be a foreign key of applications.appID.
REPLACE INTO applications (appID, status)
SELECT COALESCE(employees.appID, app2.appID) AS appIdToModify, vStatus
FROM applications AS app2
LEFT OUTER JOIN employees
ON ssn = vSSN
WHERE app2.appDate = vDate
UPDATE applications SET status = vStatus WHERE appID = #AppID LIMIT 1;
I have 2 tables: tbl_taxclasses, tbl_taxclasses_regions
This is a one to many relationship, where the main record ID is classid.
I have a column inside the first table called regionscount
So, I create a Tax Class, in table 1. Then I add regions/states in table 2, assigning the classid to each region.
I perform a SELECT statement to count the regions with that same classid, and then I perform an UPDATE statement on tbl_taxclasses with that number. I update the regionscount column.
This means I'm writing 2 queries. Which is fine, but I was wondering if there was a way to do a SELECT statement inside the UPDATE statement, like this:
UPDATE `tbl_taxclasses` SET `regionscount` = [SELECT COUNT(regionsid) FROM `tbl_taxclasses_regions` WHERE classid = 1] WHERE classid = 1
I'm reaching here, since I'm not sure how robust MySQL is, but I do have the latest version, as of today. (5.5.15)
You could use a non-correlated subquery to do the work for you:
UPDATE
tbl_taxclasses c
INNER JOIN (
SELECT
COUNT(regionsid) AS n
FROM
tbl_taxclasses_regions
GROUP BY
classid
) r USING(classid)
SET
c.regionscount = r.n
WHERE
c.classid = 1
Turns out I was actually guessing right.
This works:
UPDATE `tbl_taxclasses`
SET `regionscount` = (
SELECT COUNT(regionsid) AS `num`
FROM `tbl_taxclasses_regions`
WHERE classid = 1)
WHERE classid = 1 LIMIT 1
I just needed to replace my brackets [] with parenthesis ().