Using inner join when updating in Oracle - sql

I have 2 tables:
I want to update my table1 records with the suitable age, which can be found in table2. Unique identifier is the BVD_ID_NUMBER. I tried to do this using the following code
UPDATE table1
SET table1.age =
(select table2.age2
from
(select distinct table2.BVD_ID_NUMBER, table2.age2
FROM table1
inner JOIN table2
on table1.ACQUIROR_BVD_ID_NUMBER=table2.BVD_ID_NUMBER)
where table2.BVD_ID_NUMBER=table1.ACQUIROR_BVD_ID_NUMBER);
I received the following error:
SQL Error: ORA-00904: "ORBIS_DISTINCT"."BVD_ID_NUMBER": invalid identifier
00904. 00000 - "%s: invalid identifier"
Any help?

Hmmm. You have overcomplicated your query. Usually, when using correlated subqueries, there is no reason to mention the outer table in the inner subquery. Oracle doesn't allow scoping beyond one level for correlated subqueries, so you need to simplify for the correlation clause:
UPDATE table1 t1
SET age = (select t2.age2
from table2 t2
where t1.ACQUIROR_BVD_ID_NUMBER = t2.BVD_ID_NUMBER
);
This is likely to cause a "subquery returns more than one row" type of error. To fix that, use aggregation or rownum = 1:
UPDATE table1 t1
SET age = (select t2.age2
from table2 t2
where t1.ACQUIROR_BVD_ID_NUMBER = t2.BVD_ID_NUMBER and
rownum = 1
);

Related

sqlite DELETE (based on 2 tables) syntax (version 3.36)

I tried to delete an entry from table1 based on criteria on table2. (id in table1 is foreign key from table2)
I tried all those below and all returned with syntax errors.
take 1:
delete table1.* from table1 inner join table2 on table1.id=table2.id where table2.column3=21 and table2.column4=59;
Error: near "table1": syntax error
take 2:
delete table1 from table1 inner join table2 on table1.id=table2.id where table2.column3=21 and table2.column4=59;
Error: near "table1": syntax error
take 3:
delete from table1 inner join table2 on table1.id=table2.id where table2.column3=21 and table2.column4=59;
Error: near "inner": syntax error
Anyone knows what are the correct syntax?
If this is the wrong approach, what is the correct way to achieve my goal?
Really appreciate it.
No Join in SqlLite DELETE, by the look of it, but you could use exists:
delete
from table1
where exists
(select 1
from table2
where table1.id=table2.id
and table2.column3=21
and table2.column4=59
);
Since SQLite does not support JOIN yet in outer query of DELETE statements, consider using subquery with IN or EXISTS:
DELETE FROM table1
WHERE id IN (
SELECT id
FROM table2
WHERE table2.column3 = 21
AND table2.column4 = 59
)
DELETE FROM table1
WHERE EXISTS (
SELECT 1
FROM table2
WHERE table1.id = table.id
AND table2.column3 = 21
AND table2.column4 = 59
)

PostgreSQL UPDATE ERROR: more than one row returned by a subquery used as an expression

UPDATE t1 SET cat_id = (SELECT t2.id FROM t3 JOIN t1 ON t2.name=t3.cat);
ERROR: more than one row returned by a subquery used as an expression
ERROR: more than one row returned by a subquery used as an expression
In this situation either use IN clause OR make sur that your select statement should always return single row.
First, t2 is not defined in your expression. So the error should really be that is undefined.
Second, you seem to want a correlated subquery. If so, you don't join in the subquery:
UPDATE t1
SET cat_id = (SELECT t3.id FROM t3 WHERE t1.name = t3.cat)

Odd behavior with query using DBLink

This is will be difficult to reproduce.
A query with this pattern
SELECT *
FROM table1 t1
LEFT
JOIN table2#myLink t2
ON t1.key_field = t2.key_field
LEFT
JOIN (SELECT a.*,
3 dummyField
FROM table3#myLink a
) t3
ON T1.key_key = t3.key_Field
AND t3.dummyfield =
( SELECT 3
FROM dual
);
Fails with this error
ORA-01799: a column may not be outer-joined to a subquery
01799. 00000 - "a column may not be outer-joined to a subquery"
*Cause: <expression>(+) <relop> (<subquery>) is not allowed.
*Action: Either remove the (+) or make a view out of the subquery.
In V6 and before, the (+) was just ignored in this case.
Here's where it gets weird, this pattern works just fine:
SELECT *
FROM table1 t1
LEFT
JOIN (SELECT * FROM table2#myLink) t2 -- Note trivial subquery wrapper
ON t1.key_field = t2.key_field
LEFT
JOIN (SELECT a.*,
3 dummyField
FROM table3#myLink a
) t3
ON T1.key_key = t3.key_Field
AND t3.dummyfield =
( SELECT 3
FROM dual
);
Any thoughts? What on earth is happening here?
Also, I have these tables in the same schema in a different environment and the first query runs without error without the db links.
the problem arises on the last condition where the left side operand is column whether right side operand is subquery for the outer joined query :
AND t3.dummyfield = ( SELECT 3 FROM dual );
if you change this part as :
WHERE t3.dummyfield = ( SELECT 3 FROM dual );
your problem will be resolved.
your working query will be:
SELECT *
FROM table1 t1
LEFT JOIN table2#myLink t2
ON t1.key_field = t2.key_field
LEFT JOIN
(SELECT a.*,3 dummyField
FROM table3#myLink a) t3
ON T1.key_key = t3.key_Field
WHERE t3.dummyfield = ( SELECT 3
FROM dual
);
PS: please note that both of your queries has syntax error on the second LEFT JOIN ON operand.
PS: please note that your second query does not work as well with the JOIN (SELECT * FROM table2#myLink) t2
The following is taken from Oracle Support Doc ID 2258768.1
We do not support outer joining a column to a subquery and hence ORA-1799 is expected behavior.
However ORA-1799 incorrectly gets avoided due to query transformation when query refers local object.

Trouble with Update-Set-From syntax in Oracle

I am trying to execute a simple SQL update-set-from statement in Oracle, which looks like the one below:
update
table1 t1
set
t1.col1=t2.col1
from
(select distinct t1.col1 from table1 t1 where t1.col2='xxx') as t2
where
t1.col1='yyy';
I haven't used from with update-set before, but this syntax looks okay to me. Yet it fails with this error:
Error report -
SQL Error: ORA-00933: SQL command not properly ended
00933. 00000 - "SQL command not properly ended"
*Cause:
*Action:
My desired result is for the inner select to return a single record, which then gets inserted/updated into table1's col1.
Also, should I be using a different alias thant1 for table1 in the inner select statement, considering that I have already used t1 in the update statement?
Syntax should be
update table t1 set
t1.col1 = (select distinct t2.col1
from table1 t2
where t2.col2 = 'xxx')
where t1.col1 = 'yyy';
Note that DISTINCT doesn't necessarily mean that SELECT will return a single value; if it does not, you'll end up in TOO-MANY-ROWS error.

Oracle sql MERGE INTO with a single where clause

I have the following SQL code (this is how much I've got so far):
MERGE INTO SCHEMA1.TABLE_1 table1 USING
(
SELECT DISTINCT table2.column1,
view1.column2
FROM SCHEMA2.TABLE_2 table2
LEFT JOIN SCHEMA2.VIEW_1 view1
ON table2.column2 = view1.column3
) t2 ON (table1.column3 = t2.column1 )
WHEN MATCHED THEN
UPDATE
SET table1.column4 = t2.column2;
The following is the definition of VIEW_1 :
CREATE VIEW SCHEMA_2.VIEW_1
AS (SELECT
SCHEMA_2.TABLE_1.COLUMN_1,
SCHEMA_2.TABLE_2.COLUMN_1,
SCHEMA_2.TABLE_2.COLUMN_2,
SCHEMA_2.TABLE_2.COLUMN_3,
SCHEMA_2.TABLE_5.COLUMN_1,
SCHEMA_2.TABLE_6.COLUMN_1,
SCHEMA_2.TABLE_6.COLUMN_2,
SCHEMA_2.TABLE_6.COLUMN_3,
SCHEMA_2.TABLE_6.COLUMN_4,
SCHEMA_2.TABLE_7.COLUMN_1,
SCHEMA_2.TABLE_7.COLUMN_2,
SCHEMA_2.TABLE_8.COLUMN_1
FROM SCHEMA_2.TABLE_1
INNER JOIN SCHEMA_2.TABLE_2
ON SCHEMA_2.TABLE_1.COLUMN_1 = SCHEMA_2.TABLE_2.COLUMN_2
INNER JOIN SCHEMA_2.TABLE_5
ON SCHEMA_2.TABLE_1.COLUMN_4 = SCHEMA_2.TABLE_5.COLUMN_3
LEFT OUTER JOIN SCHEMA_2.TABLE_6
ON SCHEMA_2.TABLE_2.COLUMN_2 = SCHEMA_2.TABLE_6.COLUMN_4
LEFT OUTER JOIN SCHEMA_2.TABLE_7
ON SCHEMA_2.TABLE_2.COLUMN_1 = SCHEMA_2.TABLE_8.COLUMN_5
);
But I'm getting the below error message:
Error report -
SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
30926. 00000 - "unable to get a stable set of rows in the source tables"
*Cause: A stable set of rows could not be got because of large dml
What causes the error? Where to change in the code to make it work?
Thanks for helping out!
For this example your problem is definitely in the USING subquery. This query produces more than one value of table2.column1:
SELECT DISTINCT table2.column1,
view1.column2
FROM SCHEMA2.TABLE_2 table2
LEFT JOIN SCHEMA2.VIEW_1 view1
ON table2.column2 = view1.column3
So the ON clause will match the same row(s) in table1 more than once:
ON (table1.column3 = t2.column1 )
Oracle cannot figure out which value of t2.column2 should be used in the UPDATE, so it hurls ORA-30926.
Using distinct in the subquery doesn't help because that gives permutations of all the columns. You need to write a subquery which will produce unique values of t2.column1 across all rows, or add another identifying column(s) to generate a unique key you can join to table1.
In my experience, this error is returned, not only when the USING clause returns more than one row for a row in the MATCH table, but also frequently when it cannot be sure that only one row will be returned (even if there are no actual cases of multiple rows being returned). To force the parser to accept the query in cases like this, I usually resort to using a GROUP BY on the MATCH..ON column(s).
MERGE INTO SCHEMA1.TABLE_1 table1 USING
(
SELECT table2.column1,
MAX(view1.column2) as column2
FROM SCHEMA2.TABLE_2 table2
LEFT JOIN SCHEMA2.VIEW_1 view1
ON table2.column2 = view1.column3
GROUP BY table2.column1
) t2 ON (table1.column3 = t2.column1 )
WHEN MATCHED THEN
UPDATE
SET table1.column4 = t2.column2;