Delete result from LEFT JOIN from multiple tables SQL - sql

If I run this query,
SELECT Qry_StockData_Names.CodeName
FROM Qry_StockData_Names LEFT JOIN Tbl_StockData_Codes ON Qry_StockData_Names.CodeName = Tbl_StockData_Codes.CodeName
WHERE Tbl_StockData_Codes.CodeName IS NULL;
it returns the CodeNames that are on Qry_StockData_Names but not on Tbl_StockData_Codes (Qry_StockData_Names is just a select distinct off existing data). How can I use the result from this and delete it from 3 tables. For example, say the return result is
CodeName
ABC
DEF
I would like to remove from Tbl_StockData_Daily, Tbl_StockData_Weekly and Tbl_StockData_Monthly all the data where the CodeName's are ABC, DEF.

IN Access you can do this
DELETE FROM Qry_StockData_Names AS t1
WHERE Exists (
SELECT t2.CodeName
FROM StockData_Codes AS t2
WHERE
t2.CodeName = t1.CodeName );

For each of the tables Tbl_StockData_Daily, Tbl_StockData_Weekly and Tbl_StockData_Monthly execute a DELETE statement, for example:
DELETE FROM Tbl_StockData_Daily
WHERE CodeName IN (
SELECT Qry_StockData_Names.CodeName
FROM Qry_StockData_Names LEFT JOIN Tbl_StockData_Codes
ON Qry_StockData_Names.CodeName = Tbl_StockData_Codes.CodeName
WHERE Tbl_StockData_Codes.CodeName IS NULL
);
Or with NOT EXISTS:
DELETE FROM Tbl_StockData_Daily
WHERE CodeName IN (
SELECT n.CodeName
FROM Qry_StockData_Names AS n
WHERE NOT EXISTS (
SELECT 1
FROM Tbl_StockData_Codes AS c
WHERE c.CodeName = n.CodeName
)
);

Related

From 2 tables, get rows unique to each table

Starting with 2 tables, I want to get all rows with value in a certain column(cName) that is present on 1 table but not the other. I want to do this for both tables. I found a solution to use LEFT JOIN which gives me solution for 1 of the tables and I used UNION to combine. Is this a good way to do this or is there a better way?
select *
from College C1 LEFT JOIN myTestTable T1 on C1.cName = T1.cName
where T1.cName IS NULL
UNION
select *
from myTestTable T1 LEFT JOIN College C1 on T1.cName = C1.cName
where C1.cName IS NULL
You can use full join with a where:
SELECT *
FROM College C1 FULL JOIN
myTestTable T1
ON C1.cName = T1.cName
WHERE T1.cName IS NULL OR C1.cName IS NULL;
I prefer anti-join (NOT EXISTS) operators rather than LEFT JOIN. For one, if CName is not unique the left join produces multiple rows which the UNION must eliminate.
select * from College C1
WHERE NOT EXISTS (SELECT 1 FROM myTestTable T1 WHERE C1.cName = T1.cName)
UNION
select * from myTestTable T1
WHERE NOT EXISTS (SELECT 1 FROM College C1 WHERE T1.cName = C1.cName);
If indexes aren't available on CName you'll have some table scans with either LEFT JOIN or the NOT EXISTS.
You could also do this:
select * from College
union all
select * from myTestTable
MINUS ( select * from College intersect select * from myTestTable );

Delete two tables based on results of one join

I am trying to delete data from two tables at the same time using inner join. However when I tried to run my query, an error
SQL command not properly ended
error came out.
A brief background of what I am trying to do and some info on the tables, table1 and table2. So both tables has a same field, for instance "ABC". I would like to delete data from both tables using inner join but under the where condition of a field (XYZ) under table where it equals to a value.
This is my sql statment:
DELETE table1, table2
FROM table1
INNER JOIN table1 ON table1.ABC = table2.ABC
WHERE table1.XYZ = 'TESTIT';
You can't delete more than one table.
You must use two different DELETE statements.
For this you can create a temporary table to store IDs to delete, for example:
CREATE TABLE app (ABC varchar(100))
INSERT INTO app (ABC)
SELECT abc
FROM table1
INNER JOIN table1 ON table1.ABC = table2.ABC
WHERE table1.XYZ = 'TESTIT';
DELETE
FROM table1
WHERE table1.ABC IN (SELECT ABC FROM app);
DELETE
FROM table2
WHERE table2.ABC IN (SELECT ABC FROM app);
DROP TABLE app;
In Oracle you cannot delete from 2 tables in a single statement like you are doing. The syntax is wrong. You can use as below:
DELETE table1
where table1.ABC = (select table2.ABC
from table2
WHERE table2.ABC = table1.ABC
and table1.XYZ = 'TESTIT');
A PL/SQL solution might be something like this:
declare
type abc_tt is table of table1.abc%type index by pls_integer;
l_abc_collection abc_tt;
begin
select distinct t1.abc bulk collect into l_abc_collection
from table1 t1
join table2 t2 on t2.abc = t1.abc
where t1.xyz = 'TESTIT';
dbms_output.put_line('Stored ' || l_abc_collection.count || ' values for processing');
forall i in 1..l_abc_collection.count
delete table1 t
where t.xyz = 'TESTIT'
and t.abc = l_abc_collection(i);
dbms_output.put_line('Deleted ' || sql%rowcount || ' rows from table1');
forall i in 1..l_abc_collection.count
delete table2 t
where t.xyz = 'TESTIT'
and t.abc = l_abc_collection(i);
dbms_output.put_line('Deleted ' || sql%rowcount || ' rows from table2');
end;
Output:
Stored 1000 values for processing
Deleted 1000 rows from table1
Deleted 1000 rows from table1
Test setup:
create table table1 (abc, xyz) as
select rownum, 'TESTIT' from dual connect by rownum <= 1000
union all
select rownum, 'OTHER' from dual connect by rownum <= 100;
create table table2 as select * from table1;
After deletion there are 100 rows in each table. I have assumed we only want to delete the ones where xyz = 'TESTIT' even when abc values are common to both tables.
select distinct table1.ABC into Temptable
FROM table1
INNER JOIN table1 ON table1.ABC = table2.ABC
WHERE table1.XYZ = 'TESTIT'
delete table1 where ABC in (select ABC from Temptable)
delete table2 where ABC in (select ABC from Temptable)
drop table Temptable

SQL Select where condition : value 1 <> value 2

Need your help to know if possible to select values from a table with the below condition :
Table content : matching between 2 objects
(Id_obj_A; name_obj_A; country_obj_A; Id_obj_B; name_obj_B; country_obj_B)
Select *
from table
Where (only if country_obj_A <> country_obj_B)
Many thanks for your help
Yes. There are a few ways, one is to use NOT EXISTS like this:
select
*
from tableA
where NOT EXISTS (
select NULL
from tableB
where tableB.country_obj_B = tableA.country_obj_A
)
or, using NOT IN
select
*
from tableA
where country_obj_A NOT IN (
select country_obj_B
from tableB
)
or, using a LEFT JOIN then exclude the joined rows:
select
*
from tableA
left join tableB on tableA.country_obj_A = tableB.country_obj_B
where tableB.country_obj_B IS NULL

Select statement to select item in table 1 that does not exist in table 2

I am writing a simple select statement to compare two different tables.
table 1 table 2
a a
b b
c c
H d
e
f
I need to select any item in table 1 that does not exist in table 2.
You have a few options, one of which is
select table1.col from table1 where
not exists (select col from table2 where table2.col = table1.col)
SELECT table_1.name
FROM table_1
LEFT JOIN table_2 ON table_1.name = table_2.name
WHERE table_2.name IS NULL
Subquery should do it:
Select * from table1
where Id not in
(select distinct col from table2)
Since it looks like there is only one column.
Try this.
select * from table a -- select all of the things in a
minus
select * from table b -- remove from it the things in b

How to do a Select in a Select

I have a table containing a unique ID field. Another field (REF) contains a reference to another dataset's ID field.
Now I have to select all datasets where REF points to a dataset that doesn't exist.
SELECT * FROM table WHERE ("no dataset with ID=REF exists")
How can I do this?
3 ways
SELECT * FROM YourTable y WHERE NOT EXISTS
(SELECT * FROM OtherTable o WHERE y.Ref = o.Ref)
SELECT * FROM YourTable WHERE Ref NOT IN
(SELECT Ref FROM OtherTable WHERE Ref IS NOT NULL)
SELECT y.* FROM YourTable y
LEFT OUTER JOIN OtherTable o ON y.Ref = o.Ref
WHERE o.Ref IS NULL
See also Five ways to return all rows from one table which are not in another table
Try this:
SELECT * FROM TABLE WHERE NOT EXISTS
(SELECT * FROM OtherTable WHERE TABLE.Ref = OtherTable.ID)
I think this should work
SELECT * FROM table WHERE id NOT IN (SELECT ref_id FROM ref_table)
or with JOIN
SELECT table.*
FROM table LEFT JOIN ref_table ON table.id = ref_table.ref_id
WHERE ref_table.ref_id IS NULL
SELECT
table1.*
FROM
table1
LEFT JOIN table2 ON table1.id = table2.ref
WHERE
table2.ref IS NULL
You can do a subquery like:
select * from table where somefield not in (select otherfield from sometable where ID=REF)
SELECT *
FROM table
WHERE ((SELECT COUNT(*) FROM table2 WHERE table2.id = table.ref) = 0)
Something like that :
SELECT * FROM table WHERE ID NOT IN(SELECT REF FROM Table2 )
Yes you can use
select * from x where not exist ( select * from y )