Update referencing another table - sql

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

Related

Update query on Access database

I maintain an application developed in Access. And I have to implement an update query, but I'm quite stuck at the moment and I don't understand why.
Basically, the query must update a record from table X following another record from that same table, but the query I wrote does nothing, I did test separately the update and the select and they both work, but together, no.
I hope some of you may found my problem.
Here is the query I wrote (I did remove some fields to avoid to be too long, and of course, the query you will see was tested to be sure it was not the missing fields the issue)
UPDATE
TABLE_X AS recordToUpdate,
(
SELECT
DUP_C2B_From_CPL.[NUM-GrpHdr],
DUP_C2B_From_CPL.[NUM-LOT],
DUP_C2B_From_CPL.[SINGLE-SCENARIO],
DUP_C2B_From_CPL.EqvtAmt,
DUP_C2B_From_CPL.EqvtAmtCur,
DUP_C2B_From_CPL.EqvtAmtCurTft,
DUP_C2B_From_CPL.XchgRateInfExchangeRate,
DUP_C2B_From_CPL.XchgRateInfRateType,
DUP_C2B_From_CPL.XchgRateInfContractId,
DUP_C2B_From_CPL.ChqTp
FROM DUP_C2B_From_CPL
) AS originalRecord
SET
recordToUpdate.EqvtAmt = originalRecord.EqvtAmt,
recordToUpdate.EqvtAmtCur = originalRecord.EqvtAmtCur,
recordToUpdate.EqvtAmtCurTft = originalRecord.EqvtAmtCurTft,
recordToUpdate.XchgRateInfExchangeRate = originalRecord.XchgRateInfExchangeRate,
recordToUpdate.XchgRateInfRateType = originalRecord.XchgRateInfRateType,
recordToUpdate.XchgRateInfContractId = originalRecord.XchgRateInfContractId,
recordToUpdate.ChqTp = originalRecord.ChqTp
WHERE
recordToUpdate.[SINGLE-SCENARIO] = 112811
DUP_C2B_From_CPL here is a subQuery that is retrieving the record I'm interested in so I can take its values to update the other one.
In the last WHERE closure, I hardcoded the id for more readability for you (and yes it exists :))
And also the designer is rendering correctly, so no error on this side. But as I said, it seems that it is not updating anything.
Don't hesitate to tell me if you nee more information.
You can try something like below.
UPDATE
Table1 AS t1
INNER JOIN Table1 AS t2
ON t1.Field1 = t2.Field2
SET
T1.Field1 = t2.field1
If there is not any join then you can try like below
UPDATE Table1 t1 , Table1 t2
SET T1.Field1 = t2.field1
where t1.field1 = 'aa' and t2.field1 = 'bb'
Well, for some reason, I had to restart my laptop, and the query is now working.
Thank you for your help.

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);

Is EXISTS clause supported by DBISAM's sql engine?

Strangely, it seems that the EXISTS clause is not supported by DBISAM's sql engine, as it's always resulting in an SQL error. The following is a sample where EXISTS is being used. Am i missing anything here?
update Table1 set HASXACTION = False
WHERE EXISTS (SELECT SERIALID
From Table2
LEFT JOIN Table1 ON (Table2 .AUXILACT = Table1 .CODE)
AND (Table2 .CHARTACT = Table1 .CHARTACT) )
Never mind people, i just learned that DBISAM does not support EXISTS operator for specifying sub-select predicates in WHERE clauses. It's documented within DBISAM's help file(screenshot attached).
I presume that you don't really want the join in the subquery. You probably intend a correlated subquery:
UPDATE Table1
SET HASXACTION = False
WHERE EXISTS (SELECT SERIALID
FROM Table2
WHERE Table2.AUXILACT = Table1.CODE AND Table2.CHARTACT = Table1.CHARTACT
);
This should also fix the problem you are having, which is the reference to Table1 both in the update clause and the subquery. (This is a MySQL limitation.)
EDIT:
I cannot find any reference to EXISTS (or even subqueries) for dbisam. But, you can do updates with joins, so this should be equivalent:
UPDATE Table1
SET HASXACTION = False
FROM Table1 JOIN
Table2
ON Table2.AUXILACT = Table1.CODE AND Table2.CHARTACT = Table1.CHARTACT;
As you've already found, you can do it with the IN. However, there is a limitation that IN can only work with one field. So you can get around it by concatenating two fields to make expressions that fit the criteria. One for the inner, and one for the outer.
update Table1 set HASXACTION = False
WHERE Code+'.'+CHARTACT IN
(
SELECT AUXILACT+'.'+CHARTACT From Table2
)

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 .

How can I update a column in a table with the result of a select statement that uses row being updated as part of the where clause?

This SQL statement example is very close to what I think I need...
update table1 set value1 = x.value1 from
(select value1, code from table2
where code = something) as x
However, what I need to do is change the "something" in the above example to a value from the row that is being updated.
For example, I tried this but it didn't work:
update table1 A set value1 = x.value1 from
(select value1, code from table2
where code = A.something) as x
This is a one time operation to update an existing table and I'm not really looking for high performance way to do this. Any solution that gets the task done is good enough.
Edit for clarification
I am using Microsoft SQL Server 6.5.
Edit
I've since had several smart people tell me that many of the answers posted here should have worked. My specific sql statement was way more convoluted than the pseudo sql I used in my example. For some reason the answers I tried (most of them) did not work. The same smart people couldn't figure out why they didn't work either.
The answer I selected did work for me. Future answer seekers should probably look at several other answers below to help resolve their own questions, not just the one that solved my issue.
UPDATE is notoriously different across different DBMSes. But try something along these lines:
UPDATE Table1 SET Value1 =
(SELECT Value1 FROM Table2 WHERE code = Table1.Something)
Have you tried something like this :-
UPDATE table1
SET x.Value1=y.Value1
FROM Table1 x INNER JOIN
Table2 y ON x.Code=y.Something
Try this
UPDATE table1 AS a
SET value1 = x.value1
FROM table2 AS x
WHERE x.code = a.something
Sounds like it should work like this:
Update table1 Set value1 =
( Select value1
From table2
Where table2.code = table1.something
)
UPDATE Table1, Table2
SET Table1.Value1 = Table2.Value1
WHERE Table2.Code = Table1.Something
Does this help?
Try this one:
update table1
set value1 = x.value1
from table2 x
where something = x.code
"I am using Microsoft SQL Server 6.5"??
Why?
Why don't you get the FREE SQL 2008 Express edition or if you qualify, SQL 2008 Developers Edition for about USD50?