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