i am curious about how updating a table with inner join works. if i run the following statement:
update tbl1 a
inner join tbl2 b using (id)
set a.val = b.val;
what happens to the records in tbl1 that do not have a match in tbl2? will they simply not be updated and left as is in tbl1? will they be deleted?
i realize i can run this and get the answer but i'm also interested in the mechanics of how this works behind the scenes and was hoping somebody could elucidate this for me.
The update statement is operating on tbl1.
The join is providing a filter that specifies which rows to update in tbl1.
As an added bonus, the join is also providing a value for the column.
The update statement does not and cannot delete rows from a table.
Q: What happens to the records in tbl1 that do not have a match in tbl2?
A: They will not be updated since they have no match from tbl2. From the definition, the INNER JOIN keyword return rows when there is at least one match in both tables. The only keyword that could delete record from your table is the DELETE DML.
Related
I'm going to delete some rows in one of my table called sy_user. I want to delete some of the rows that is not matched in the other table, which is the tb_master_pegawai.
How do i solve this query to do the row delete using the subquery as the WHERE condition?
I used subquery as the WHERE condition in the DELETE query. When i run it in phpmyadmin it says
You can't specify target table 'sy_user' for update in FROM clause
But when i simulate it, it has return rows.
DELETE FROM sy_user
WHERE user_id NOT IN
(SELECT tbpeg.ID
FROM tb_master_pegawai AS tbpeg
JOIN sy_user AS tbuser ON tbpeg.ID=tbuser.user_id)
I expect the result is i have deleted the rows that are not matched with the same data in the other table.
You can't reference your the table you are deleting from in a subquery of DELETE/UPDATE queries. Instead, use a LEFT JOIN and check where the joined table is NULL (meaning it had no rows that matched the ON condition).
Try to run delete queries within a transaction when testing it, that way you can rollback if the query deleted more rows than intended.
DELETE u
FROM sy_user AS u
LEFT JOIN tb_master_pegawai AS tp
ON tp.ID = u.user_id
WHERE tp.ID IS NULL
You could simplify your request using only a LEFT JOIN:
DELETE sy_user FROM sy_user
LEFT JOIN tb_master_pegawai ON sy_user.user_id = tb_master_pegawai.ID
WHERE tb_master_pegawai.ID IS NULL
As development DB I am using MySQL, and for tests I am using H2 database.
The following script works in MySQL very well, but it is fails on H2.
UPDATE `table_a`
JOIN `table_b` ON `table_a`.id=`table_b`.a_id
SET `table_a`.b_id=`table_b`.id
In the internet I found that h2 doesn't support UPDATE clause with JOIN. Maybe there is a way to rewrite this script without JOIN clause?
By the way, I am using liquibase. Maybe I can write UPDATE clause with it's xml language?
I tried the following script
UPDATE table_a, table_b
SET table_a.b_id = table_b.id
WHERE table_a.id = table_b.a_id
But I still getting errors. Seems, that H2 doesn't support updating multiple tables in one query. How can I rewrite this query in two different queries to collect ids and insert them?
Try something like this:
update table_a a
set a.b_id = (select b.id from table_b b where b.a_id = a.id)
where exists
(select * from table_b b where b.a_id = a.id)
I've spend a lot of time for this kind of UPDATE. Please find out my comment, maybe somebody find it usefull:
For every rows in WHERE condition executed UPDATE for SET
In inner SELECT you can use updated table columns
In case of error "Scalar subquery contains more than one row" - UPDATE for SET return more, than one row. Problem rows could be found with replace UPDATE by SELECT COUNT(*)
See also Scalar subquery contains more than one row
Sample SELECT WITH UPDATE:
UPDATE USER_DETAILS UD SET UD.GRADUATE_COMMENT=
(SELECT U.COMMENT FROM USERS U WHERE u.ID=UD.id) <-- ref to outer updated table
WHERE UD.GRADUATE_COMMENT IS NULL;
I have this MySQL Update statement. It works fine.
UPDATE Table1
SET Table1_field1='field1_content', Table1_field2='field2_content'
where Table1_field3=2
All the fields above belong to the same table. I then added an extra condition AND Table2.fieldname='XXX' to the WHERE clause
UPDATE Table1
SET Table1_fieldname1='field1_content', Table1_fieldname2='field2_content'
where Table1_fieldname3=2 AND Table2.fieldname='XXX'
This time, the SQL statement fails. The error is "unknown column Table2.fieldname in where clause". However, Table2.fieldname does exist.
In order to be able to use fields from Table2 in your query you'll need use a JOIN between Table1 and Table2.
A JOIN effectively combines a row from each table into a single row for your query, based on a provided condition.
For example if both Table1 and Table2 have a column tableID, we can combine rows from each table where the tableIDs match.
The query would then look like below:
UPDATE Table1
JOIN Table2
ON Table1.tableID = Table2.tableID
SET Table1_fieldname1='field1_content', Table1_fieldname2='field2_content'
WHERE Table1_fieldname3=2 AND Table2.fieldname='XXX';
The JOIN keyword is equivalent to INNER JOIN. There are different types of JOINs available and I'd recommend reading up about them.
Here's a reference image to give you an idea of the different types:
you need to join table 1 and table2; then you can update
UPDATE Table1 AS b
INNER JOIN Table2 AS g ON b.id = g.id SET Table1_fieldname1='field1_content', Table1_fieldname2='field2_content'
where Table1_fieldname3=2 AND g.fieldname='XXX'
I found several questions with similar wording, but none addressed the specific question I have.
How does one perform an UPDATE with conditions that operate between two unlinked tables?
As example
TABLE_I
ID, Placed, junk, junk, junk
TABLE_II
ID, Category, Placed, Note, junk, junk...
If the Condition is in TABLE_II
WHERE Category=9 AND Note=#testvalue
An UPDATE should take place where a value in TABLE_II matches one in TABLE_I
UPDATE TABLE_I SET Placed=#testvalue WHERE
.. the Current TABLE_I.Placed=Table_II.Placed assuming the above conditions are met
Is such stepped-in conditioning even possible in SQL? Or would it require coding outside of the query to test in steps?
SQL
update t1 SET t1.Placed=#testvalue
from Table_1 t1
join Table_2 t2 on t1.placed = t2.placed
where t2.Category=9 AND t2.Note=#testvalue
you have to use join in the update statement
Mysql
the answer is yes you can
try it like that
update Table_1 t1
join Table_2 t2 on t1.placed = t2.placed
where t2.Category=9 AND t2.Note=#testvalue
SET t1.Placed=#testvalue
EDIT:
For general Update join :
UPDATE TABLEA a
JOIN TABLEB b ON a.join_colA = b.join_colB
SET a.columnToUpdate = [something]
You could do this kind of stuff with a trigger on insert on table_i combined with a procedure for updating the first table.
Not sure on how to do it in MySQL or SQL-server (why 2 tags? Which is it?), but it probably is not much different from doing this in PostgreSQL. A quick Google search gave me http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html
Though the best solution probably is to actually link the unlinked tables.
I have two tables with varchar columns having common values.
I am trying to perform a simple inner join on the tables on those varchar columns but I am getting empty set as a result.
There are null values present in these columns.
Collation for both columns are same.
I googled for it but cant find a solution.
The query is a simple join query and doesn't have any syntax issues.
When I change the inner to left join I get a resultset but all the columns in the right table are empty even for the rows passes the join condition.
I created two dummy tables with a common varchar to run a join query and it works.
So it is not a bug.So what are the possible reasons for getting empty sets any guesses.
The server is mysql version 5.5.37
update a set a.id=x where a.col in(Select col from b where .....);
Another issue is that i have a query like above but when I run it It kind of hangs...On running
SHOW PROCESSLIST;
the status is sending data...
What does it mean?
Can anyone help me.
Edit 1
The query is like this
UPDATE table1 bo INNER JOIN table2 ae
ON bo.joincol=ae.joincol AND ae.criteriaFieldName='UNSPSC' AND ae.taskId=4 AND ae.batchId = 44
SET bo.taskid=ae.taskId WHERE bo.procesId = 44 AND (taskid IS NULL OR taskid = 0);
Table1 contains 50+ columns
Table2 contains 8 columns
Unfortunately I can't disclose the data.
Interesting fact is if I join them using taskId I get a resultset.
For your second issue, try doing it as a JOIN instead of using IN:-
UPDATE a
INNER JOIN b
ON a.col = b.col
WHERE ........
SET a.id=x