not in operator in SQL - sql

there is 2 tables
table1
ID
1
2
4
6
7
TABLE2
2
4
6
i want those number from table1 which is not in table2 how i do this ?
i try this
select id from table1 t1
inner join table2 t2 on t1.id=t2.id
where t1.id not in (select id from table2)
but this is not working

SELECT t1.id
FROM table1 t1
LEFT JOIN table2 t2 ON t2.id = t1.id
WHERE t2.id IS NULL
Conceptually, we select all rows from table1 and for each row we attempt to find a row in table2 with the same value for the id column. If there is no such row, we just leave the table2 portion of our result empty for that row. Then we constrain our selection by picking only those rows in the result where the matching row does not exist. Finally, We ignore all fields from our result except for the id column (the one we are sure that exists, from table1).

try this:
select id from table1 t1 where t1.id not in (select t2.id from table2 t2)

You don't need to join the two tables in this case. You could just do
select id from table1 A where A.id not in (select B.id from table2 B);
You could also just simply use the sql set difference EXCEPT operator to achieve this
(select id from table1) except (select id from table2);

Use NOT IN or NOT EXISTS
select id from table1 t1
where t1.id not in (select id from table2)
select id from table1 t1
where not exists (select id from table2 where id = t1.id)

Related

Oracle Sql - I have two tables and need to filter table1 with results from table2. I need to return all of table1 if table2 is empty

I'm currently turning a comma-separated string into a number table with the field name of ID. I'm then trying to do an nvl to select all if the generated table is null.
table1.ID = NVL(table2.ID, table1.ID)
I have two tables and need to filter table1 with results from table2. I need to return all of table1 if table2 is empty.
Scenario I
Table1
ID
1
2
3
4
Table2 (Empty)
ID
Return rows 1, 2, 3, 4
Scenario II
Table1
ID
1
2
3
4
Table2
ID
2
3
Return rows 2, 3
You can use filtering in the where clause:
select t1.id
from table1 t1
where not exists (select 1 from table2) or
exists (select 1 from table2 t2 where t2.id = t1.id);
I don't think join is the right way to express this logic.
You can also use UNION
select t1.id
from table1 t1
where not exists (select 1 from table2 where id = t1.id) union all
select t2.id
from table2 t2
where exist (select 1 from table1 where id = t2.id);

SQL Server - Return all records from LEFT table and only non matching records from right table

I have 2 tables with the same structure (field names). Table1 and Table2.
I need to return all records from Table1 and only records from Table2 that do not match/join to a record in Table1.
Table2 has more records than Table1.
I am joining the 2 tables on 3 fields.
So basically I want all records from table1 returned and only records that don't have a match (joining on the 3 fields) to table1 from table2 returned.
Put another way, Table1 records take precedence over table2 records in my final result output when the records exist in both tables (same value for the 3 fields)
I started writing something like the below but I don't think it will work. Should I use a left outer join instead?
Select * from table1 t1
left join table2 t2 on t1.id = t2.id and t1.date = t2.date and t1.custid= t2.custid
where t2.id is null or t2.date is null or t2.custid is null
So, you need every row from table1 plus the rows from table2 that don't match with table1?:
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2 t2
WHERE NOT EXISTS(SELECT * FROM table1
WHERE id = t2.id
AND date = t2.date
AND custid = t2.custid);
Select * from table1 t1
Union
Select * from table2 t2
Where Not exists
(Select * from table1
Where id = t1.id
and date = t1.date
and custid= t1.custid)

Applying joins conditionally in SQL Server

I have some set of records, but now i have to select only those records from this set which have theeir Id in either of the two tables.
Suppose I have table1 which contains
Id Name
----------
1 Name1
2 Name2
Now I need to select only those records from table one
which have either their id in table2 or in table3
I was trying to apply or operator witin inner join like:
select *
from table1
inner join table2 on table2.id = table1.id or
inner join table3 on table3.id = table1.id.
Is it possible? What is the best method to approach this? Actually I am also not able to use
if exist(select 1 from table2 where id=table1.id) then select from table1
Could someone help me to get over this?
Use left join and then check if at least one of the joins has found a relation
select t1.*
from table1 t1
left join table2 t2 on t2.id = t1.id
left join table3 t3 on t3.id = t1.id
where t2.id is not null
or t3.is is not null
I would be inclined to use exists:
select t1.*
from table1 t1
where exists (select 1 from table2 t2 where t2.id = t1.id) or
exists (select 1 from table3 t3 where t3.id = t1.id) ;
The advantage to using exists (or in) over a join involves duplicate rows. If table2 or table3 have multiple rows for a given id, then a version using join will produce multiple rows in the result set.
I think the most efficient way is to use UNION on table2 and table3 and join to it :
SELECT t1.*
FROM table1 t1
INNER JOIN(SELECT id FROM Table2
UNION
SELECT id FROM Table3) s
ON(t.id = s.id)
Alternatively, you can use below SQL as well:
SELECT *
FROM dbo.Table1
WHERE id Table1.IN ( SELECT table2.id
FROM dbo.table2 )
OR Table1.id IN ( SELECT table3.id
FROM Table3 )

How to check if two selects return the same ids

Suppose, we have query like this:
SELECT
1
FROM DUAL WHERE
(SELECT id FROM table_1 t1 WHERE /*conditions*/)
IN
(SELECT id FROM table_1 t2 WHERE /*conditions*/)
I want to check if first query
SELECT id FROM table_1 t1 WHERE /*conditions*/
returns the same ids like the second query.
Of course this query (IN statement) doesn't work.
Try:
SELECT id FROM table_1 t1 WHERE /*conditions1*/ and id not in (SELECT id FROM table_1 t2 WHERE /*conditions2*/)
union
SELECT id FROM table_1 t1 WHERE /*conditions2*/ and id not in (SELECT id FROM table_1 t2 WHERE /*conditions1*/)
If both queries gives you the same id's the result should be empty.
This will return nothing if sets are equal:
SELECT id FROM table_1 t1 WHERE /*conditions*/
EXCEPT
SELECT id FROM table_1 t2 WHERE /*conditions*/
You can use EXCEPT.
EXCEPT returns distinct rows from the left input query that aren’t
output by the right input query.
EXCEPT sample in your case:
SELECT id
FROM table_1 AS t1
WHERE /*conditions*/
EXCEPT
SELECT id
FROM table_1 AS t2
WHERE /*conditions*/
Just as an alternative method that used Full Join in tsql:
SELECT CASE WHEN isnull(Count(*), 0) > 1 then 1 else 0 end as result
FROM (SELECT t1.id as t1_id, t2.id as t2_id FROM
(SELECT id FROM table1 WHERE /*conditions*/) As t1
Full Outer Join
(SELECT id FROM table2 WHERE /*conditions*/) As t2
On t1.id = t2.id
) As ft
WHERE ft.t1_id is null or ft.t2_id is null
And I think this can marked as a stupid way.

Quicker way to insert non-matching ids to column

Is there a quicker way to get the ids that exist in table1 but not exist in table2 and insert them in table2?
insert into table2 (id)
select id
from table1
where table1.id not in (select id from table2)
In addition to your solution using the in operator try the exists one
select id
from table1 t1
where not exists (
select 1
from table2
where id = t1.id
)
If the subquery returns an empty set not exists evaluates to true
The outer join
select id
from
table1 t1
left join
table2 t2 on t1.id = t2.id
where t2.id is null
Use explain analyze to compare