Query to output not existing data - sql

Table A:
id Name
1 a
2 b
3 c
4 d
5 e
Table B:
id Name
3 c
4 d
5 e
Here, id is the primary key connected to Table B.
I need output like this:-
id
1
2
That means, which ids in Table A are not present in Table B

Use EXCEPT operator:
select id from tableA
except
select id from tableB

You can use a left join, which will preserve all records on the left side and associate them with null if no matching record is available on the right side.
This way you can then filter on the right side columns to be null to get the desired outcome
select t1.id
from tableA t1
left join
tableB t2
on t1.id = t2.id
where t2.id is null

Use NOT EXISTS in WHERE clause
SELECT id FROM TableA A
WHERE NOT EXISTS(SELECT 1 FROM TableB B WHERE A.id = B.Id )

Using Not in statement.
Try this:-
Select id from TableA
where id not in (Select id from TableB);

You can use minus:
select * from tableA
minus
select * from tableB

Related

SQL Server: how can I count values in one field different from another, with multiple values for same identifier?

I have two tables with one common column, and an identifying value that can be duplicate (several observations of same document).
An example:
TableA:
A_identifier | Value
-------------+-------
1 | A
1 | B
TableB:
B_identifier | A_identifier | Value
-------------+--------------+-------
1 | 1 | A
2 | 1 | B
3 | 1 | B
4 | 1 | C
The above example illustrates the type of situation I am looking for in my data - we have a case in TableA with multiple values, of which some are the same in TableB and some are not. So TableA.Value and TableB.Value represent the same concept.
I want to know for each TableA.A_identifier, how many rows of TableB have different values than TableA.Value. If there was only one observation per A_identifier, this could be solved with a not, but the multiple possible values prevent this.
What I have thought about doing is something like this (which does not work):
select distinct
b.B_identifier, a.A_identifier
from
TableB b
join
TableA a in b.A_identifer = a.A_identifier and b.Value != a.Value
While the query technically works, it returns the wrong result - it counts all the cases where the values in TableA and TableB are different in a given row. However, I want it to only count the values in TableB which are not present at all in TableA for each A_identifier.
I tried replacing the != with not in which is what I would do for a static parameter. This syntax is not supported.
I hope my question makes sense, and that somebody can help. Thank you in advance.
Try this query if it works for you,
SELECT COUNT(b.A_identifier)
FROM TableB b
LEFT JOIN TableA a
ON b.A_identifier = a.A_identifier
AND b.Value = a.Value
WHERE a.A_identifier IS NULL -- filters out inexisting value
AND EXISTS (SELECT 1
FROM TableA c
WHERE b.A_identifier = c.A_identifier) -- shows only A_identifier
-- that is present in TableA
However, if you want to get the count for each Value
SELECT b.A_identifier, b.Value, TOTAL_COUNT = COUNT(b.A_identifier)
FROM TableB b
LEFT JOIN TableA a
ON b.A_identifier = a.A_identifier
AND b.Value = a.Value
WHERE a.A_identifier IS NULL
AND EXISTS (SELECT 1
FROM TableA c
WHERE b.A_identifier = c.A_identifier)
GROUP BY b.A_identifier, b.Value
Use NOT EXISTS
select t1.A_identifier, count(t2.value)
from TableA t1
left join TableB t2 on t1.A_identifier = t2.A_identifier and
NOT EXISTS (
select 1
from TableA t3
where t3.A_identifier = t2.A_identifier and
t3.Value = t2.Value
)
group by t1.A_identifier
How about the following SQL?
select distinct TableA.A_identifier,
(select count(*) from TableB
where TableB.A_identifier = TableA.A_identifier
and not exists(
select * from TableA where A_identifier = TableB.A_identifier
and Value = TableB.Value)
)
as TableB_Rows
from TableA

Joining two tables where id does not equal

I'm struggling getting this query to produce the results I want.
I have:
table1, columns=empid, alt_id
table2, columns=empid, alt_id
I want to get the empid, and alt_id from table 1 where the alt_id does not match the alt_id in table2. They will both have alt_id numbers I just want to get the ones that do not match.
Any ideas?
SELECT * FROM table1
INNER JOIN table2 ON table2.empid = table1.empid AND table2.alt_id <> table1.alt_id
What does that really mean though? Normally when this is asked, it is of the form "I want all rows from A that have no row matching in B and all in B that have no match in A"
Which looks like this:
SELECT * FROM
A
FULL OUTER JOIN
B
ON
a.id = b.id
You'll see a null for any row data where there isn't a matching row on the other side:
A.id
1
2
B.id
1
3
Result of full outer join:
A.id B.id
1 1
2 null
null 3
You, however have asked for A-B join where the IDs aren't equal, which would be the more useless query of:
SELECT * FROM
A
INNER JOIN
B
ON
a.id != b.id
And it would look like:
A.id B.id
1 3
2 1
2 3
You seem to want not exists:
select t1.*
from table1 t1
where not exists (select 1 from table2 t2 where t2.alt_id = t1.alt_id);
It is unclear whether or not you also want to join on empid, so you might really want:
select t1.*
from table1 t1
where not exists (select 1 from table2 t2 where t2.alt_id = t1.alt_id and t2.empid = t1.empid);
A left join will find all records in Table A that do not match those in Table B. Then use a Where filter to find the Nulls from Table B. That will give you all those in Table A that do not have a matching ID in Table B.
Select A.*
from Table A
Left Join
Table B
on a.altid = b.altid
where b.altid is null;
select *
from [Login] L inner join Employee E
on l.EmployeeID = e.EmployeeID
where l.EmployeeID not in (select EmployeeID from Employee)

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

SQL: select all unique values in table A which are not in table B

I have table A
Id | Name | Department
-----------------------------
0 | Alice | 1
0 | Alice | 2
1 | Bob | 1
and table B
Id | Name
-------------
0 | Alice
I want to select all unique Ids in table A which do not exist in table B. how can I do this?
select distinct id
from TableA a
where not exists (
select id
from TableB
where id = a.id
)
Just to provide a different solution than NOT IN :
SELECT DISTINCT A.Id
FROM A
LEFT OUTER JOIN B
ON A.Id = B.Id
WHERE B.Id IS NULL
The "good" solution is usually MINUS or EXCEPT, but MySQL doesn't support it.
This question was asked a few time ago and someone posted an article comparing NOT IN, NOT EXISTS and LEFT OUTER JOIN ... IS NULL. It would be interesting if someone could find it again!
The most efficient answer is to use a left join, as using "NOT IN" can sometimes prevent a query from using an index, if present.
The answer in this case would be something like
SELECT DISTINCT
*
FROM
TableA a
LEFT JOIN
TableB b
ON
a.Id = b.Id
WHERE
b.Id IS NULL
Alternatively, this is more readable than a left join, and more efficient than the NOT IN solutions
SELECT * FROM TableA a where NOT EXISTS (SELECT * FROM TableB where Id = a.Id)
I'd use a NOT EXISTS Like this:
SELECT A.Id
FROM TableA A
WHERE NOT EXISTS (SELECT B.Id FROM TableB B WHERE A.Id = B.Id)
GROUP BY A.Id
SELECT DISTINCT Id FROM A WHERE Id NOT IN (SELECT ID FROM B);
SELECT DISTINCT Id FROM A WHERE Id NOT IN(SELECT DISTINCT Id FROM B);
The subquery will get all the IDs in B. The group by...having will get all the unique IDs in A that are also not in B.
select *
from A
where id not in
(
select distinct id
from B
)
group by ID
having count(*) > 1;

select a value where it doesn't exist in another table

I have two tables
Table A:
ID
1
2
3
4
Table B:
ID
1
2
3
I have two requests:
I want to select all rows in table A that table B doesn't have, which in this case is row 4.
I want to delete all rows that table B doesn't have.
I am using SQL Server 2000.
You could use NOT IN:
SELECT A.* FROM A WHERE ID NOT IN(SELECT ID FROM B)
However, meanwhile i prefer NOT EXISTS:
SELECT A.* FROM A WHERE NOT EXISTS(SELECT 1 FROM B WHERE B.ID=A.ID)
There are other options as well, this article explains all advantages and disadvantages very well:
Should I use NOT IN, OUTER APPLY, LEFT OUTER JOIN, EXCEPT, or NOT EXISTS?
For your first question there are at least three common methods to choose from:
NOT EXISTS
NOT IN
LEFT JOIN
The SQL looks like this:
SELECT * FROM TableA WHERE NOT EXISTS (
SELECT NULL
FROM TableB
WHERE TableB.ID = TableA.ID
)
SELECT * FROM TableA WHERE ID NOT IN (
SELECT ID FROM TableB
)
SELECT TableA.* FROM TableA
LEFT JOIN TableB
ON TableA.ID = TableB.ID
WHERE TableB.ID IS NULL
Depending on which database you are using, the performance of each can vary. For SQL Server (not nullable columns):
NOT EXISTS and NOT IN predicates are the best way to search for missing values, as long as both columns in question are NOT NULL.
select ID from A where ID not in (select ID from B);
or
select ID from A except select ID from B;
Your second question:
delete from A where ID not in (select ID from B);
SELECT ID
FROM A
WHERE NOT EXISTS( SELECT 1
FROM B
WHERE B.ID = A.ID
)
This would select 4 in your case
SELECT ID FROM TableA WHERE ID NOT IN (SELECT ID FROM TableB)
This would delete them
DELETE FROM TableA WHERE ID NOT IN (SELECT ID FROM TableB)
SELECT ID
FROM A
WHERE ID NOT IN (
SELECT ID
FROM B);
SELECT ID
FROM A a
WHERE NOT EXISTS (
SELECT 1
FROM B b
WHERE b.ID = a.ID)
SELECT a.ID
FROM A a
LEFT OUTER JOIN B b
ON a.ID = b.ID
WHERE b.ID IS NULL
DELETE
FROM A
WHERE ID NOT IN (
SELECT ID
FROM B)