Replace NOT IN with LEFT JOIN to obtain the same result - sql

I've a doubt about the second query in PL/SQL. I've this query:
DELETE FROM tableA
WHERE id NOT IN (SELECT c_id FROM tableB WHERE tableB.c_id = tableA.id)
Is it possible or correct change for something like this?:
DELETE FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.c_id
WHERE id IS NULL
But this show an error: syntax error near at or near "LEFT"
Can anyone help me?

Is it possible or correct change for something like this?:
DELETE FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.c_id
WHERE id IS NULL
No, it is not possible nor correct as Oracle does not support the non-standard DELETE FROM ... JOIN syntax.
You can use:
DELETE FROM tableA a
WHERE NOT EXISTS (SELECT 1 FROM tableB b WHERE b.c_id = a.id);
or:
DELETE FROM tableA
WHERE id NOT IN (SELECT c_id FROM tableB);

MT0's answer is probably what you want. I only want to add that there is a third method that could be useful in more advanced situations:
MERGE INTO tableA
USING (SELECT tableA.rowid AS row_id
FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.c_id
WHERE tableB.c_id IS NULL) src
ON (src.row_id = tableA.rowid)
WHEN MATCHED THEN UPDATE SET tableA.othercol=null -- meaningless change
DELETE WHERE 1=1

Related

How can I use a comparison operator in a DELETE in PostgreSQL?

DELETE FROM tableA a
WHERE 0 = (SELECT b.quantity
FROM tableB b
WHERE a.id=b.id)
This is a example query, but i need to say if i can use the comparison operator = after the WHERE.
Try this:
DELETE FROM tableA
WHERE Id IN(SELECT id FROM tableB WHERE quantity=0)

Inner Join Delete in SQL Server 2008?

I am trying to join 2 tables together and do a delete on it.
DELETE TableA
FROM TableA a
INNER JOIN
TableB b on b.Id = a.Id
where title like 'test'
The above is what I come up with however I keep getting
The DELETE statement conflicted with the REFERENCE constraint
I thought if I merge the 2 tables together then I will delete both at the same time and no constraints would be conflicted.
Am I missing something in my query?
try this:
DELETE TableA
FROM TableA
INNER JOIN
TableB b on b.Id = TableA.Id
where TableA.title like 'test'
First try to delete TableB with that title condition
Then delete those records in TableA
DELETE FROM TableB
WHERE Id IN
( SELECT Id FROM TableA WHERE title = 'test')
DELETE FROM TableA
WHERE title = 'test'
Referential Constraints blocks you from deleting rows in TableA when you still have reference in TableB
I would delete one after the other with cascade constraint.

SQL Delete based on condition in join

It is possible to delete records based on a satisfied condition with a join query?
For instance, I have a linking table joining 3 records. The query I have at the moment deletes records from this table where one of the id's isn't IN() an imploded Php array. I've come to realise that the query should only remove records from this table if the id's don't exist in the array and they belong to a certain other table based on the a link to another table.
For SQL Server, the command is slightly different:
DELETE FROM TableA
FROM TableA LEFT OUTER JOIN TableB ON TableA.Column = TableB.Column
WHERE TableB.Column IS NULL
No, that's not a typo, yes, you do need "FROM TableA" twice. At least, you need the second FROM (the first is optional). The following has the advantage that it works for both SQL Server and MySQL:
DELETE TableA
FROM TableA LEFT OUTER JOIN TableB ON TableA.Column = TableB.Column
WHERE TableB.Column IS NULL
I like to use EXISTS clauses for this:
DELETE FROM TableA
WHERE
<<put your array condition here>>
AND NOT EXISTS
(SELECT 1 FROM TableB Where TableB.ID=TableA.ID)
You can use :
DELETE Based on a Join:
DELETE A
FROM TableA AS A
LEFT OUTER JOIN TableB As B ON A.Id = B.TabaleAId
WHERE B.Column IS NULL
Delete With SubQuery:
DELETE
FROM TableA AS A
Where
A.id not in ( Select B.TabaleAId From Tab;eB As B )
or
DELETE FROM TableA
WHERE Not EXISTS
(
SELECT *
FROM TableB As B
Where B.TableAId = TableA.Id
)
DELETE Using Table Expressions:
With A
As
(
Select TableA.*
FROM TableA AS A
LEFT OUTER JOIN TableB As B ON A.Id = B.TabaleAId
WHERE B.Column IS NULL
)
Delete From A
DELETE FROM TableA
LEFT OUTER JOIN TableB
WHERE TableB.Column IS NULL
Will delete the records in tableA that don't have a corresponding record in TableB. Is that like what you are after?
DELETE FROM a
FROM TableA AS a LEFT OUTER JOIN TableB AS b
on a.CALENDAR_DATE = b.CALENDAR_DATE AND a.ID = b.ID
Where b.ID is null
You can first use the select statement and verify your records that you want to delete and then remove the select statement and add Delete FROM tablename with the above query syntax.
The easiest way to Delete based on join is as follow:
1.Write your query using SELECT statement instead of DELETE statement
SELECT COLUMNS
FROM Table1
INNER JOIN Table2 ON Table1.YYY = Table2.XXX
2.Replace SELECT COLUMNS with DELETE FROM TABLE
DELETE FROM Table1
FROM Table1
INNER JOIN Table2 ON Table1.YYY = Table2.XXX
Note that we need to specify FROM twice, one for DELETE part and one for JOIN part.
delete from TableA
where id in
(
select id from TableA
except select id from TableB
)
Which means "delete from tableA where id in table a but not in table b)
Otherwise a Merge statement might help you (when matched/not matched delete etc)
http://technet.microsoft.com/en-us/library/bb510625.aspx

How do I get all records from tableA with a left outer join and a where condition on tableB?

Basically, what I want is if there is a record in tableB of type 'X' I want to see it, otherwise I don't, but I want all records from tableA.
I know I could accomplish this by putting the tableB.type = 'X' in the LEFT OUTER JOIN ON clause, but I can't do that because I'm limited to using only the where condition because I'm using a restricted query manager of a program I won't name, but I definitely hate. :)
SELECT *
FROM tableA
LEFT OUTER JOIN ON tableA.ID = tableB.ID
WHERE tableB.type = 'X'
How do I accomplish this?
EDIT
I've tried this, but I still don't get all records from tableA. I'm testing this on SQL server to avoid waiting for long periods for my query to run on the production system. I'm pretty sure the production system is using Oracle if that helps.
SELECT *
FROM tableA LEFT OUTER JOIN ON tableA.ID = tableB.ID
WHERE tableB.type = 'X' OR tableB.type IS NULL
Check for nulls in tableB:
SELECT *
FROM tableA LEFT OUTER JOIN ON tableA.ID = tableB.ID
WHERE tableB.type = 'X'
OR tableB.type IS NULL
That will get you everything from both tables when the join matches, and everything from tableA when there's no corresponding record in tableB.
If type can be null naturally, you'll want to change the condition to something more sound:
SELECT *
FROM tableA LEFT OUTER JOIN ON tableA.ID = tableB.ID
WHERE tableB.type = 'X'
OR tableB.ID IS NULL
Assuming ID is the primary key and cannot be null naturally, that will get the same result.
Don't know if you have access to the database, or if you have to query tableB specifically due to some other restriction, but you could always create a view of table b called tableBTypeX where the view is restricted to only those rows with type = x. Then you could left outer join against tableBTypeX . In your query, the join columns are ID columns, so they probably have indexes, making the query fine in terms of speed. In the case where the join columns are not indexed, joining against the view would be more efficient, because fewer rows are joined against, and joining against unindexed rows usually requires a full table scan, making it a much more time consuming query.
You can join against the "type X" records from tableB exclusively by amending the join condition:
SELECT
*
FROM
tableA
LEFT OUTER JOIN ON
tableA.ID = tableB.ID
AND tableB.type = 'X'
Is UNION possible?
SELECT *
FROM tableA
LEFT OUTER JOIN ON tableA.ID = tableB.ID
WHERE tableB.type = 'X'
UNION
SELECT *
FROM tableA
... or a CTE? Not sure how the name tableB would resolve though and can't test...
;WITH tableB AS
(
SELECT * FROM tableB WHERE type = 'X'
)
SELECT *
FROM
tableA
LEFT OUTER JOIN
tableB ON tableA.ID = tableB.ID

Retrive Records Form One Table as long as they do not exist in Another table T-SQL [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL?
I need to wite a query that will retrieve the records from Table A , provided that the key in Table A does not exist in Table B.
Any help will be appreciated.
Thanks
select a.*
from
tableA a
left join tableB b
ON a.id = b.id
where
b.id is null
SELECT *
FROM A
WHERE ID NOT IN
(SELECT ID FROM B)
None of the above solutions would work if the key comprises of multiple columns.
If the tables have compound primary keys, you'll have to use a "NOT EXISTS" clause similar to the one below.
SELECT *
FROM TableA AS a
WHERE NOT EXISTS (
SELECT *
FROM TableB b
WHERE b.id1 = a.id1
AND b.id2 = a.id2
AND b.id3 = a.id3
);
Use a left join. The DB tries to map datasets from TableB to TableA using the id fields. If there is no fitting data set available in TableB, the TableB data gets NULL. Now you just have to check for TableB.id to be NULL.
SELECT TableA.* FROM TableA LEFT JOIN TableB ON TableA.id = TableB.id WHERE TableB.id IS NULL
Assuming:
TableA's Id = Id
TableB's Id = Id
select * from TableA ta where ta.Id not in (select Id from TableB)
SELECT * FROM TableA
WHERE NOT Exists(SELECT * FROM TableB WHERE id=TableA.id)
also works and it's almost self documenting...