Update columns in multiple tables with inner join - mysql

Edit Turns out there is an H2 database sitting on top of the mysql database. The query I write hits the H2 instead. I'll keep researching to see if this will work
I have two tables I would like to update at the same time, and the values from one of them is determined by values stored in the other. My update query looks like this:
UPDATE table1 AS A INNER JOIN table2 AS B
ON A.COL1 = B.COL1
AND A.COL2 = B.COL2
SET A.COL3 = 'SOME VAL',
B.COL4 = B.COL4 - A.COL4,
B.COL5 = B.COL5 - A.COL4
WHERE A.ID IN (23,5,21)
I'm getting a syntax error that says 'Expected "SET"' right where I'm doing the INNER JOIN.
I believe I should be able to do this join update per UPDATE multiple tables in MySQL using LEFT JOIN and http://dev.mysql.com/doc/refman/5.0/en/update.html. Does anybody know what my syntax error is?
Update for posterity
First, thanks to Thomas Mueller for his help.
I ended up using the following syntax and as I found it somewhat confusing, I'm leaving it here for future viewers.
UPDATE TABLE1 SET(COL1, COL2) =
( SELECT T1.COL1 - T2.AMNT, T1.COL2 + T2.AMNT
FROM TABLE1 T1 RIGHT JOIN TABLE2 T2
ON T1.COL3 = T2.COL3
AND T1.COL4 = T2.COL4
WHERE T2.ID = 23)
WHERE EXISTS
( SELECT *
FROM TABLE2
WHERE TABLE1.COL3 = TABLE2.COL3
AND TABLE1.COL4 = TABLE2.COL4
AND TABLE2.ID = 23)
Note: I had to use a join in the first select as I couldn't get the syntax we discussed below to work.
As a result of using this method, if I get a list of table2 ids (23,5,21 in my original example) I have to do multiple update statements. If anybody knows a better way to do this, please let me know.

H2 does not support updating two tables at the same time within one SQL statement. You would need to use two statements. For the supported syntax, see the UPDATE statement railroad diagram.

Related

Left join FROM multiple tables

This question is different than the ones I have seen already answered. Is it possible to left join using multiple 'FROM' tables? When I try it (with other code, but the principle is the same) I get the error 'Unknown column 'table1.otherId' in 'on clause'. Any help would be greatly appreciated.
Something like this:
SELECT *
FROM table1, table2
LEFT JOIN other_table
ON other_table.id = table2.id
AND other_table.otherId = table1.otherId
Try like this:-
SELECT *
FROM table1
LEFT JOIN other_table
ON table1.id=other_table.id LEFT JOIN table2 ON
other_table.otherId = table2.id
It depends what you want to do. You seem to want a Cartesian product of the first two tables with lookups on the third:
SELECT *
FROM table1 CROSS JOIN
table2 LEFT JOIN
other_table
ON other_table.id = table2.id AND
other_table.otherId = table1.otherId;
Commas -- which should just be banned permanently from FROM clauses -- are similar to CROSS JOINs. However, the parsing of the SQL statement is different. A comma prevents the tables before it from being used in ON clauses after it; that is the source of your error.
Answer is "No"
But you can do it this way:
SELECT * FROM table2, other_table ON other_table.id = table2.id
LEFT JOIN table1 ON other_table.otherId = table1.otherId

Merging two MySQL Tables SQL Statement

I'm trying to "merge" two tables and have found a few examples but I'm having difficulty applying them as it continues to say I have syntax error:
UPDATE T2
SET payable_id = T1.payable_id, payable_type = T1.payable_type
FROM payments_distributions AS T2
JOIN payables AS T1
ON T1.payments_distribution_id = T2.id
It mentions that the FROM is at an invalid position at the moment.
I'd appreciate the help. Thanks
Move the SET clause to the end and all of the table references after UPDATE.
UPDATE payments_distributions t2
INNER JOIN payables t1
ON t1.payments_distribution_id = t2.id
SET t2.payable_id = t1.payable_id,
t2.payable_type = t1.payable_type;

Add a column with a value from another table with if condition [duplicate]

I want to update a table in a statement that has several joins. While I know the order of joins doesn't really matter (unless you you are using optimizer hints) I ordered them a certain way to be most intuitive to read. However, this results in the table I want to update not being the one I start with, and I am having trouble updating it.
A dummy example of what I'd like to do is something like:
UPDATE b
FROM tableA a
JOIN tableB b
ON a.a_id = b.a_id
JOIN tableC c
ON b.b_id = c.b_id
SET b.val = a.val+c.val
WHERE a.val > 10
AND c.val > 10;
There are many posts about updating with joins here however they always have table being updated first. I know this is possible in SQL Server and hopefully its possible in MySQL Too!
The multi-table UPDATE syntax in MySQL is different from Microsoft SQL Server. You don't need to say which table(s) you're updating, that's implicit in your SET clause.
UPDATE tableA a
JOIN tableB b
ON a.a_id = b.a_id
JOIN tableC c
ON b.b_id = c.b_id
SET b.val = a.val+c.val
WHERE a.val > 10
AND c.val > 10;
There is no FROM clause in MySQL's syntax.
UPDATE with JOIN is not standard SQL, and both MySQL and Microsoft SQL Server have implemented their own ideas as an extension to standard syntax.
You have the ordering of the statements wrong. You can read up on the syntax here (I know, it's pretty hard to read.
UPDATE tableA a
JOIN tableB b
ON a.a_id = b.a_id
JOIN tableC c
ON b.b_id = c.b_id
SET b.val = a.val+c.val
WHERE a.val > 10
AND c.val > 10;
sql fiddle
Another correct construction, which we can use in this situation:
UPDATE T1, T2,
[INNER JOIN | LEFT JOIN] T1 ON T1.C1 = T2.C1
SET T1.C2 = T2.C2,
T2.C3 = expr
WHERE condition
The above example is take from: MySQL UPDATE JOIN.
Reaching for the MySQL 8.0 Reference Manual we will find such a description of multiple-table UPDATE syntax:
UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET assignment_list
[WHERE where_condition]
The table_references clause lists the tables involved in the join.
So multiple-table MySQL's syntax doesn't support FROM, ORDER BY or LIMIT clauses as opposed to single-table syntax.
This link should give you the syntax that MySQL needs and here is an example. Why do you need to join the two tables? is it to limit the records updated? I am asking because you can also do something like the following:
update B set B.x=<value>
where
B.<value> is in(
select A.y
from A left outer join B on A.<value>=B.<value>
)

MySql Query If Field equals Field in different table update different field

I have got two tables. I want to update MODEL in table2 when ITEM in table1 equals ITEM in table2.
Any Ideas?
In MySQL, you do it like this
UPDATE table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id
SET t1.col1 = t2.col1,
t1.col2 = t2.col2
If I understand correctly, you just want to perform an UPDATE on table2 based on, presumably, foreign keys?
If that's right, this should work:
UPDATE
table2
JOIN table1
ON table1.ITEM = table2.ITEM
SET
MODEL = 'new value';
The table declaration in an UPDATE statement is the same as is specified in a SELECT statement - so you can use any type of JOIN that fits your table/data.
Docs for UPDATE, SELECT.
If you could add an actual query attempt, or something, that might be helpful. Can you try something like the following:
UPDATE table2 JOIN table1 ON table2.ITEM = table1.ITEM SET MODEL = ?

SQL: How can we make a table1 JOIN table2 ON a table given in a field in table1?

Imagine I have table1 which has a column named 'table_name'. I use table1.table_name to store the name of another table in the database. The referenceable tables would all have a field 'target_id.
Is is possible to use table_name in a JOIN statement?
For example:
SELECT t1.*, t2.* FROM table1 AS t1
JOIN table1.table_name AS t2 ON t1.table1_id = t2.target_id
The obvious solution is to use the script (C++ in my case) to get the table name first, and construct a SQL query from it. The question is: can we bypass the script and do this directly in SQL (MySQL)?
Edit: What is dynamic SQL?
The only chance you have is to do 2 SQL statements:
select the tablename you need
use this table-name to dynamically build the secound query to get the data you need - what you want isn't possible to do with SQL directly (and it sounds like you've designed your database wrong in some way - but that's hard to say without knowing what's the goal of it).
I know I'm late to the party, but I wanted to offer a different solution. I see this sort of thing a lot in audit tables. The column table_name would refer to "what table was changed" and table1_id would refer to the ID of the row that changed in that table. In this case, the audit table is pointing back to many different tables that don't normally get joined.
Here goes:
SELECT t1.*, t2.*, t3.*, t4.*, t5.*
FROM table1 AS t1
left JOIN table2 AS t2
ON t1.table1_id = t2.target_id
and t1.table_name = 'table2'
left JOIN table3 AS t3
ON t1.table1_id = t3.target_id
and t1.table_name = 'table3'
left JOIN table4 AS t4
ON t1.table1_id = t4.target_id
and t1.table_name = 'table4'
left JOIN table5 AS t5
ON t1.table1_id = t5.target_id
and t1.table_name = 'table5'
Of course, the main drawback is that each table that can be possibly referenced needs to be explicitly included in the SQL command.
You can get more elegant output using this as your select list:
SELECT
t1.*,
coalesce(t2.fieldA, t3.fieldA, t4.fieldA, t5.fieldA) as fieldA,
coalesce(t2.fieldB, t3.fieldB, t4.fieldB, t5.fieldB) as fieldB
etc