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;
Related
I am trying to left join two tables (A and B) together and would like to return all values that have a column in table B marked as null in mySQL.
The two tables I am joining are both very large and I am running into an issue where my connection will timeout after 6000 seconds due to the DBMS settings; is there a way to make this query run more efficiently?
Another bit of information: Even if I limit the query to 10 rows, it will still timeout and give me the error code listed below.
select *
from Table_A a
left join Table_B b
on a.field_X = b.field_X
where b.Field_X is null;
I am experiencing the following error code: "Error Code 2013. Lost Connection to MySQL server during query."
Side note: I am a new SQL user and may need to ask for clarification on some answers. Thank you in advance!
First, you only need columns from a because the b columns are all null. You can write this as:
select a.*
from Table_A a left join
Table_B b
on a.field_X = b.field_X
where b.Field_X is null;
Then for this query, I recommend an index on table_b(field_x).
Maybe something like this will work for you:
select * from table_A a where a.field_X not in (select field_x from table_B);
Try the other way around, and reduce your SELECT fields if you can:
select Table_B.Field_X
from Table_B b
left join Table_A a
on a.field_X = b.field_X
where a.Field_X is null;
Let SQL do its work they way it likes to do it :) To have a standard left join (where you are looking for rows that do NOT match on the right) is highly optimised if you have the correct indexes
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 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.
I'm a beginner in MS ACCESS.
I need to join two tables: table_A and table_B. Since I want to use Replace function, but it doesn't work. My stupid code is:
UPDATE table_A
INNER JOIN table_B
SET table_A.name = table_B.name
ON table_A.age = Replace(table_B.age, "years-old","")
What's wrong with this?
You must fully define the data source(s) before the SET clause. So move the ON condition up one line:
UPDATE table_A
INNER JOIN table_B
ON table_A.age = Replace(table_B.age, "years-old","")
SET table_A.name = table_B.name
However that ON expression could be tricky. The Access query designer doesn't cooperate well with ON expressions which include functions. But the query could work if both table_A.age and table_B.age are text data type.
I suggest you first work this out as a SELECT query. Once you have the join set up and working, you can transform it from a SELECT to an UPDATE.