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
)
Related
I get the error
[Code: 10002, SQL State: 42000]
Error while compiling statement: FAILED: SemanticException [Error 10002]: Line 11:60 Invalid column reference 'FIELD3'
when running the following query:
CREATE TABLE NEW_TABLE
AS
SELECT
T1.*,
T2.*,
T3.*
FROM
OLD_TABLE1 T1
LEFT JOIN
OLD_TABLE2 T2 ON (T1.FIELD1 = T2.FIELD1)
LEFT JOIN
OLD_TABLE3 T3 ON (T1.FIELD3 = T3.FIELD3);
What is the potential issue of the above query? I double checked that the FIELD3 exists in OLD_TABLE1 and OLD_TABLE3.
One major issue you have is that duplicated column names in the table. At the very least, the JOIN conditions will introduce duplicates. There might be other duplicates as well.
List the columns you want explicitly:
CREATE TABLE NEW_TABLE AS
SELECT . . . -- list column names explicitly
FROM OLD_TABLE1 T1 LEFT JOIN
OLD_TABLE2 T2
ON T1.FIELD1 = T2.FIELD1 LEFT JOIN
OLD_TABLE3 T3
ON T1.FIELD3 = T3.FIELD3;
This problem may occur with CREATE TABLE. That said, it is more common with aggregation queries.
I have two tables with same structure that can have duplicated records, I want to identify which ones from table 2 already exists in table 1 and delete them from table 2. The following SELECT returns the duplicated records I want to delete. None of these tables have a primary key, so I need to do multiple 'ON' to identify unique records.
SELECT V.*
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3;
Then I insert this as a subquery for the DELETE:
DELETE FROM table2
WHERE table2.column1 IN
(SELECT V.*
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3);
When running this query I get the following error:
You have written a query that can return more than one field without using the reserved word EXISTS in the FROM clause of the main query. Correct the SELECT instruction of the subquery to request a single field.
I also tried this way, but it deletes all the records from table 2, not only the result of the subquery:
DELETE FROM table2
WHERE EXISTS
(SELECT V.*
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3);
This is the first solution I came up with, but I'm wondering if it wouldn't be easier to do in MS Access inserting into table1 all the records from table2 that doesn't match, and then delete table2.
All sugestions will be appreciated :)
Take the advice of the error message and try using exists logic:
DELETE
FROM table2 t2
WHERE EXISTS (SELECT 1 FROM table1 t1
WHERE t1.column1 = t2.column1 AND
t1.column2 = t2.column2 AND
t1.column3 = t2.column3);
The problem with your current exists attempt is that the query inside the EXISTS clause always has a result set, and that result set is independent of the outer delete call. So, all records get deleted.
I think you're just missing the specific column in your subquery.
This should work better :
DELETE FROM table2
WHERE table2.column1 IN
(SELECT V.column1
FROM table2 AS V
INNER JOIN table1 AS N
ON V.column1 = N.column1 AND V.column2 = N.column2 AND V.column3= N.column3);
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;
SO I've searched high and low, trying other tips used on this forum to no avail.
So trying to delete using inner join in Oracle SQL Developer (v3.2.20.09)
Table I wish to delete from (Table1, column name Column1), where the data matches the column 'Column2' in 'Table2.
I know there are some differences between Oracle/Microsoft SQL, tried multiple queries such as below, with slight variation (using open/close brackets, inner joins, WHERE EXISTS, WHERE (select's).
TRY:
delete from table2 where
exists (select column1 from table1);
delete from table2,
inner join table1 on table2.column2 = table1.column1;
What are the problem(s) of the code that I wrote?
The EXISTS version would look like this:
delete from table2
where exists (select *
from table1
where table1.column1 = table2.column2);
Alternatively you can use an IN clause
delete from table2
where column2 in (select column1
from table1);
If you're trying to delete from table1, then that's the table name that has to be used in the delete clause, not table2.
delete table1 t1
where exists (select null
from table2 t2
where t2.column2 = t1.column1)
In postgresql I can use subquery in join condition
SELECT *
FROM table1 LEFT JOIN table2
ON table1.id1 = (SELECT id2 FROM table2 LIMIT 1);
But when I try to use it in Access
SELECT *
FROM table1 LEFT JOIN table2
ON table1.id1 = (SELECT TOP 1 id2 FROM table2);
I get syntax error. Is it actually impossible in Access or just my mistake?
I know that I can get the same result with WHERE, but my question is about possibilities of JOIN in Access.
It's not possible, per the MSDN documentation:
Syntax
FROM table1 [ LEFT | RIGHT ] JOIN table2 ON table1.field1 compopr table2.field2
And (emphasis mine):
field1, field2: The names of the fields that are joined. The fields must be of the same data type and contain the same kind of data, but they do not need to have the same name.
It appears you can't even have hard-coded values in your join; you must specify the column name to join against.
In your case, you would want:
SELECT *
FROM Table1
LEFT JOIN (
SELECT DISTINCT TOP 1 ID
FROM Table2
ORDER BY ID
) Table2Derived ON Table1.ID = Table2Derived.ID