select all rows in A where there is a code in B named 'C1' but there is NOT a code in B named 'N1'.
I suspect your spec doesn't accurately convey what you actually require!
A literal interpretation would be
if there exists a row in B where CODE = 'C1'
and there does not exist a row in B where CODE = 'B1'
then return all rows from A
(that is, there is no correlation between the values in A and B respectively)
e.g.
SELECT *
FROM A
WHERE EXISTS (
SELECT *
FROM B
WHERE CODE = 'B1'
)
AND NOT EXISTS (
SELECT *
FROM B
WHERE CODE = 'C1'
);
However, experience (alone) tells us that you probably want to correlate the tables using A.ID = B.FK_ID
. See Magnus's answer for one approach.
Note the existential and non-existential operators alluded to here are known as semi join and semi difference respectively and there are different ways they can be written in SQL. Which will be most efficient from a performance point of view will depend on many variables, including SQL engine, data, indexes, statistics, etc. You will need to test using typical data. Also consider that readability and ease of maintenance are important factors too.
This candidate query (or something similar) is could be worth considering if your SQL product of choice supports the minus operator EXCEPT
(actually called MINUS
in Oracle):
SELECT *
FROM A
WHERE ID IN (
SELECT FK_ID
FROM B
WHERE CODE = 'B1'
EXCEPT
SELECT FK_ID
FROM B
WHERE CODE = 'C1'
);