I have two tables that need the exact same values for denormalization purposes.
Here's the query.
first table
UPDATE Table_One
SET win = win+1, streak = streak+1, score = score+200
WHERE userid = 1 AND lid = 1 LIMIT 1
second table
UPDATE Table_Two
SET win = win+1, streak = streak+1, score = score+200
WHERE userid = 1 LIMIT 1
As you can see the only difference between both tables is their name and table two doesn't have the field lid
Anyway to combine both updates to just one?
It should be possible with a multi-table update, as described in the documentation.
http://dev.mysql.com/doc/refman/5.5/en/update.html
UPDATE Table_One a INNER JOIN Table_Two b ON (a.userid = b.userid)
SET
a.win = a.win+1, a.streak = a.streak+1, a.score = a.score+200,
b.win = b.win+1, b.streak = b.streak+1, b.score = b.score+200
WHERE a.userid = 1 AND a.lid = 1 AND b.userid = 1
Note: Multi-table doesn't support LIMIT, so this could cause more grief depending on the details.
Stored procedures or transactions may be a nicer solution.
If there is a one to one or one to many relation from Table_One to Table_Two, this would work:
UPDATE Table_One T1, Table_Two T2
SET T1.win = T1.win+1, T1.streak = T1.streak+1, T1.score = T1.score+200,
T2.win = T2.win+1, T2.streak = T2.streak+1, T2.score = T2.score+200
WHERE T1.userid = 1 AND T1.lid = 1 AND T2.userid = T1.userid;
If you can join the tables, then you could create a view of two tables, then update via that view. In your example it looks like userid might be a suitable key.
In creating the view, you'd need to stick to the following guidelines.
They’re two separate queries and so must be treated as such. Sorry to say it, but if you’re updating two tables with identical data, there’s probably a better way to design your database. Remember to keep your programming DRY.
Edit: Should retract that; you can use it for multiple tables, but you can’t use ORDER BY or LIMIT.
Related
I am not sure how to ask this question - it might be answered somewhere, but it's kind of messy ;)
There are two tables that sort flags (labels) for objects somewhere else.
Table 1: the flags in booka_flags
columns of interest are id(INT) and title(VARCHAR)
Table 2: the flag items in booka_flags_items
columns of interest are id(INT) and flag(VARCHAR)
I want to change booka_flags_items.flag from VARCHAR (which is available from booka_flags.title) to ID (which is available from booka_flags.id)
My "idea" of writing this query (after some research) was the following:
UPDATE
booka_flags_items
SET
booka_flags_items.flag = booka_flags.id
FROM
booka_flags_items
INNER JOIN
authors
ON
booka_flags_items.flag = booka_flags.title
but it does not work. Also not working is this query:
UPDATE
booka_flags_items
SET
booka_flags_items.flag = (
SELECT booka_flags.id
FROM booka_flags
INNER JOIN booka_flags_items
ON booka_flags_items.flag = booka_flags.title
)
What would be the right way to solve a query like that?
I'm guessing you would like to update id column of booka_flags with id column of booka_flags where title matches flags. Your updated query looks incorrect as per mysql
Try:
UPDATE booka_flags_items t1 INNER JOIN booka_flags t2 On t1.flag = t2.title
SET t1.id = t2.id
I need to update a column with values from another table ... but it takes forever or aborts. A specific security (isin) can be listed at multiple exchanges (mic) ... so I think I need to have two conditions in the INNER JOIN ... ON (??). Are my attempts below correct? I have about 170,000 records in the table with 40,000 unique isins.
First try:
SQL:
SET SESSION SQL_BIG_SELECTS = 1;
UPDATE securities_live t1
INNER JOIN securities_prev t2
ON t1.isin = t2.isin AND t1.mic = t2.mic
SET t1.prev_close = t2.close;
Second try:
SQL:
SET SESSION SQL_BIG_SELECTS = 1;
UPDATE securities_live t1
INNER JOIN securities_prev t2
ON (t1.isin = t2.isin AND t1.mic = t2.mic)
SET t1.prev_close = t2.close;
Edit regarding indexes for both tables at the moment:
Indexes (securities_live):
Primary|Unique=Yes|Packed=no|Column=id|Cardinality=166776|Collation=A
Indexes (securities_prev):
Primary|Unique=Yes|Packed=no|Column=id|Cardinality=166776|Collation=A
In both tables I have a primary key on column 'id'. So e.g. in table securities_live 'Create a new index' one for column isin and another one for column mic? What about Index name and index type (Primary, Index, Unique, Fulltext)? Size?
For this query:
UPDATE securities_live t1 INNER JOIN
securities_prev t2
ON t1.isin = t2.isin AND t1.mic = t2.mic
SET t1.prev_close = t2.close;
I would suggest an index on securities_prev(isin, mic, close).
However, I suspect that you are updating all or almost all records. If that is the case, it is usually faster to truncate the table and re-populate it with insert. Update is best used for updating a relatively small number of rows.
As the commenters have noted, since you have your indexes set, I suggest you try to do these piecemeal. Do them at 5k a time until it is complete. Try 10k. Obviously you cannot do 170k or 40k. I have had many times where a database had millions of rows, and I had to to them 100k or less at a time. This was because of the limitations of the hardware.
For example,
UPDATE top(1000) securities_live t1
INNER JOIN securities_prev t2
ON t1.isin = t2.isin AND t1.mic = t2.mic
SET t1.prev_close = t2.close;
You may wish to use Order By so you know what records are what and you need keep track of what has been updated.
See here,
how can I Update top 100 records in sql server
Sorry, I just read you were using MySQL,
MySQL - UPDATE query with LIMIT
Try This:
SET SESSION SQL_BIG_SELECTS = 1;
UPDATE securities_live t1
INNER JOIN securities_prev t2
ON (t1.isin = t2.isin AND t1.mic = t2.mic)
SET t1.prev_close = t2.close;
I need to update 1 table with data from another where two fields match. I have a query but it's just locking up.
I have an employees_training_courses table
I have a company_training_categories table
I need to get the ID from company_training_categories where both the name and the account_id are the same in both tables.
So far I have this...
update employee_training_courses tc join company_training_categories ctc on ctc.name = tc.name AND ctc.account_id = tc.account_id set tc.company_training_category_id = ctc.id;
i can leave the query running, but it's clearly getting hung up somewhere !
This is your query:
update employee_training_courses tc join
company_training_categories ctc
on ctc.name = tc.name AND ctc.account_id = tc.account_id
set tc.company_training_category_id = ctc.id;
This is a very reasonable query. You probably just need indexes to speed it up. I would recommend:
create index idx_company_training_categories_2 on company_training_categories(name, account_id)
or even:
create index idx_company_training_categories_3 on company_training_categories(name, account_id, id)
Modified some stuff from my pic so you guys can understand it
I have this database. I am trying to update a value from a table based on another value from an another table.
I want to update the SUM from salary like this :
( sum = presence * 5 )
This is what I've been trying to use ( unsuccessful )
update table salary
set suma.salary = users.presence * 5
FROM salary INNER JOIN users1 INNER JOIN presence on id_salary = id_presence
I am not sure what to do, I'd appreciate some help, Thanks
In MySQL to UPDATE tables with a join you use this syntax:
UPDATE table1, table2
SET table1.column = some expression
WHERE table1.column = table2.column
That said, even with the updated picture, in your SQL you are mentioning columns that I cannot understand in which table are to be found. You also have an inner join between salariu and users1, with no join condition. Could you please clean up the question and make everything clear?
Assuming you are making the updates to the db structure you were talking about, then you can start working on this one maybe:
UPDATE salary, presence
SET salary.sum = SUM(presence.hours) * 5
WHERE presence.id = salary.id
AND <some filter on the month that depends on salary.date>
Another way, but I'm not sure it is supported in all RDBMS, would be something like this:
UPDATE salary
SET sum = (
SELECT SUM(presence.hours) * 5
FROM user, presence
WHERE presence.id = salary.id
AND <some filter on the month that depends on salary.date>
)
I'm trying to a create an update statement along the following lines:
TABLE car: id | owner_id | type | status
An owner can have multiple cars.
UPDATE car c
SET c.type = 1
WHERE c.owner_id IN ($ids)
AND c.status = [1 IF THIS OWNER HAS A CAR WITH 1, ELSE A CAR WITH 0] // ... ???
$ids is reasonably small (under 50 values).
It seems simple but I can't seem to get my head around it because I can't use a SELECT subquery with an UPDATE to the same table.
Anyone?
Thanks
You say you have tried a query that fails but unfortunately you have not posted it, so I'm going to guess that it is this:
UPDATE car c
SET c.type = 1
WHERE c.owner_id IN ($ids)
AND c.status = (SELECT MAX(c2.status) FROM car c2 WHERE c.owner_id = c2.owner_id)
Posting your actual query would be helpful, but for now I'm just going to assume that this is what you tried. If you have something slightly different, it doesn't matter... the principle is the same. It fails as you as you correctly pointed out because you cannot update and select from the same table in one query. One way to workaround this error is to wrap the select in another select:
UPDATE car c
SET c.type = 1
WHERE c.owner_id IN ($ids)
AND c.status = (SELECT * FROM
(SELECT MAX(c2.status) FROM car c2 WHERE c.owner_id = c2.owner_id)
AS T1)
Surprisingly, this will work even though it seems that it should be equivalent to the first query. Note though that the reason why the original query doesn't work is because it doesn't correctly lock the table. This workaround tricks MySQL into allowing the query anyway, but you should be aware that it may be unsafe to use in a multi-user environment.