HSQLDB update field of one table from field of another one - sql

Trying to do this:
UPDATE table1 t1
SET cost = t2.price
FROM table2 t2
WHERE t1.item_id = t2.item_id
It's working on PostgreSQL but not working on HSQLDB.
How to fix this script to support working both on PostgreSQL and HSQLDB?

The UPDATE ... FROM syntax is non-standard. This is Standard SQL and works in HSQLDB (and apparently in PostgreSQL). I am really surprised that PostgreSQL 9.4 syntax documentation does not mention this syntax which has been in the Standard since 1992.
UPDATE table1 t1
SET cost = (SELCT t2.price
FROM table2 t2
WHERE t1.item_id = t2.item_id)

HSQLDB does not support UPDATE ... FROM statements. On HSQLDB use the MERGE statement instead. Out of my head, hoping this does not contain syntax errors:
MERGE INTO table1 USING table2 ON table1.item_id = table2.item_id
WHEN MATCHED THEN UPDATE SET table1.cost = table2.price
Unfortunately, as of today postgres does not seem to support the MERGE statement, but only the similar UPSERT.

Related

SQL - Update table values from values in another table

I have a select statement that is showing me all the data from table original every time it does not match the values on table real_values.
So every time it does not match, instead of showing me which routes have the wrong values for capacity, I would like the query to update it with the correct values.
Here is a shorter version to use as an example:
http://sqlfiddle.com/#!4/6a904/1
Instead of being a select statement, how could I just update the values? I have tried some things I've seen online but nothing seems to work.
#DavidFaber's answer is how most people would do this. However, for this kind of query, I prefer to use merge over update:
MERGE INTO original o
USING real_values rv
ON (o.origin = rv.origin AND o.destination = rv.destination)
WHEN MATCHED THEN
UPDATE SET
o.capacity_wt = rv.capacity_wt, o.capacity_vol = rv.capacity_vol
WHERE o.capacity_wt != rv.capacity_wt
OR o.capacity_vol != rv.capacity_vol
(It was unclear to me from your question whether you want to update original or real_values, so I chose one. If I got this wrong, reversing it should be trivial.)
I find merge more readable and easier to use when you want to update multiple columns.
The usual form of such an update query in Oracle is the following:
UPDATE table1 t1
SET t1.value = ( SELECT t2.value FROM table2 t2
WHERE t2.key = t1.key )
WHERE EXISTS ( SELECT 1 FROM table2 t2
WHERE t2.key = t1.key );
I'm confused though. You've tagged this question oracle and sql-server but your fiddle link uses MySQL.
In SQL Server, you would do this
update original set capacity_wt=b.capacity_wt,capacity_vol=b.capacity_vol
from original a, real_values b
where a.origin = b.origin
and a.destination = b.destination
and (a.capacity_wt != b.capacity_wt
or b.capacity_vol != b.capacity_vol);

Update referencing another table

I have a statement that needs writing (with generic names for stuff, since this is for work) to update a column 'updCol' in table 'tUpd'. tUpd also has a column 'linkCol' which is present in another table tOther. tOther has another column 'idCol'.
My problem is to update the updCol value of rows in tUpd which correspond via linkCol to rows with a given idCol value.
One solution I think should work is the following;
update
tUpd
set
updCol = XXX
where exists (
select
idCol
from
tOther
where
tOther.linkCol = tUpd.linkCol
and tOther.idCol = MY_ID
)
However, I have worries that this approach will lead to poor performance, since I've been warned of sub-queries in relation to performance before - this sub-query will be run once for each row of tUpd, is this correct?
Has anyone got a better suggestion?
Important Update: my workplace avoids using SQL JOINs at all costs, preferring to join within the where clauses using, eg, where a.col = b.col. This is arguably rather awkward but allows a flexibility in especially logging which I don't fully understand. SO, I'm looking for non-JOIN-using solutions :)
All the above solutions gives an error in Informix as it cannot find the one of the table.
Here is a solution for this which worked for me:
update table1
set table1.field2 = (select table2.field2 from table2 where table1.field1 = table2.field1)
where table1.field1 in (select table2.field1 from table2)
edit: A multi-column solution from another question
update table1
set (table1.field2, table2.field3) = (
(select table2.field2, table2.field3
from table2
where table1.field1 = table2.field1)
)
where table1.field1 in (select table2.field1 from table2)
Its simply like this
UPDATE DestinationTable
SET DestinationTable.UpdateColumn = SourceTable.UpdateColumn
FROM SourceTable
WHERE DestinationTable.JoinColumn = SourceTable.JoinColumn
Maybe it will help you
update tUpd
set tU.updCol = XXX
from tOther tot, tUpd tU
where tot.linkCol = tU.linkCol
and tot.idCol = MY_ID
Here is link to similar problem.
This works for Informix Databases:
UPDATE dest_table V
SET field_1 =
(SELECT field_1 FROM source_tbl WHERE field_2 IS NULL
AND field_1 = V.field_1);
Reference

Update takes too much time at Oracle

I use oracle 10.
I have update statement like that :
update table1 t1
set v_value=(select v_value
from table2 t2
where t2.user_id=t1.user_id
and t2.item_id=t1.item_id )
It works but takes too much time. How can I optimize it ?
You can try a merge statement:
merge into table1 t1
using
(
select user_id,
item_id,
v_value
from table2
) t2 ON (t1.user_id = t1.user_id and t1.item_id = t1.item_id)
when matched then update
set v_value = t2.v_value;
(you might need to check the syntax, there were same changes to which parts in a MERGE are mandatory and which not between 10 and 11 - haven't used 10g for a long time)
It is almost impossible to tune a statement just by looking at it.
get explain plan, it will tell you if you are using a full table scan (set autotrace on).
I also suggest to use a free tool, i just posted - odbtools.com. It allows you to analyze your statement and generate the explain plan, It will show you if you have a full table scan and your select part doesn't use an index.

Update using Join(s) - Multi DB/Table

I have a scenario where I would like to update multiple fields in multiple Tables using just one instuction. I need a Syntax to perform such opperations on multiple Databases (Oracle and MSSQL).
At the moment I am stuck at the following statement from MSSQL:
update table1
set table1.value = 'foo'
from table1 t1 join table2 t2 on t1.id = t2.tab1_id
where t1.id = 1234
I would like to update a field in t2 aswell in the same statement.
Further I would like to perform the same Update(s) on Oracle.
EDIT:Seems like I can not update multiple Tables in just one statement. Is there a syntax that works for Oracle and MSSql when updating using a Join?
Regards
Seems like I can not update multiple
Tables in just one statement.
Is there a syntax that works for
Oracle and MSSql when updating using a
Join?
I assume when you re-posed the question you want syntax that will work on both Oracle and SQL Server even though it will inevitably affect only one table.
Entry level SQL-92 Standard code is supported by both platforms, therefore the following 'scalar subqueries' SQL-92 code should work:
UPDATE table1
SET my_value = (
SELECT t2.tab1_id
FROM table2 AS t2
WHERE t2.tab1_id = table1.id
)
WHERE id = 1234
AND EXISTS (
SELECT *
FROM table2 AS t2
WHERE t2.tab1_id = table1.id
);
Note that while using the correlation name t1 for Ttble1 is valid syntax according to the SQL-92 Standard this will materialize a table and the UPDATE will then target the materialized table 't1' and leave your base table 'table1` unaffected, which I assume is not the desired affect. While I'm fairly sure both Oracle and SQL Server are non-compliant is this regard and that in practise would work as expected, there's no harm in being ultra cautious and sticking to the SQL-92 syntax by fully qualifying the target table.
Folk tend not to like the 'repeated' code in the above subqueries (even though the optimizer should be smart enough to evaluate it only once).
More recent versions of Oracle and SQL Server support both support Standard SQL:2003 MERGE syntax, would may be able to use something close to this:
MERGE INTO table1
USING (
SELECT t2.tab1_id
FROM table2 AS t2
) AS source
ON id = source.tab1_id
AND id = 1234
WHEN MATCHED THEN
UPDATE
SET my_value = source.tab1_id;
I just noticed your example is even simpler than I first thought and merely requires a simple subquery that should run on most SQL products e.g.
UPDATE table1
SET my_value = 'foo'
WHERE EXISTS (
SELECT *
FROM table2 AS t2
WHERE t2.tab1_id = table1.id
);
on Oracle, you can update only one table , but you could think of using a trigger .

Strange UPDATE syntax in MS Access 2003

I've got an Access application with an update query with the following syntax:
UPDATE TABLE1, TABLE2 SET
TABLE2.VALUE1 = TABLE1.VALUE1,
TABLE2.VALUE2 = TABLE1.VALUE2,
TABLE2.VALUE3 = TABLE1.VALUE3,
TABLE2.VALUE4 = TABLE1.VALUE4
The query is working but I do not understand what's going on here.
I'm trying to convert this query to SQL Server.
Can somebody please explain what this query does? My guess is that it's a special Access syntax.
Thanks,
Sven
It uses the older implicit JOIN syntax, although SQL Server should understand that syntax too.
It's INNER JOINing table1 and table2, then moving the values from table1 to table2. Because of the lack of JOIN conditions, if table1 has more than 1 row it may have unpredictable results.
Essentially it is:
UPDATE Table1 INNER JOIN Table2 <<ON Missing Conditions Here>>
SET Table2.Value1 = Table1.Value1
Table2.Value2 = Table1.Value2
Table2.Value3 = Table1.Value3
Table2.Value4 = Table1.Value4
You can convert this to SQL Server with something like this:
UPDATE Table2
SET Table2.Value1 = Table1.Value1
Table2.Value2 = Table1.Value2
Table2.Value3 = Table1.Value3
Table2.Value4 = Table1.Value4
FROM Table1 INNER JOIN Table2 <<ON Missing Conditions Here>>
Every field from TABLE2 will override corresponded field from TABLE1 with records from TABLE1 one by one. Result will be TABLE2 with all replaced records by last row from TABLE1. If TABLE1 has no records - no changes happens.
Sorry for my english.
And... it is SQL.
Try to avoid the "UPDATE with join" syntax in SQL Server. It is completely non-standard SQL but more seriously it gives unpredictable results without any error or warning if the joining criteria is not correct. Use the MERGE statement instead or use the standard version of the UPDATE statement (with a subquery) if you can.