Reputation: 771
I have this table
FieldA | FieldB
---------------
1 12
1 13
1 14
2 12
2 13
3 12
3 13
I want to obtain FieldA, where FieldB is equal to 12, but also equal to 13, but NOT equal to 14.
Expected output:
FieldA
-------
2
3
So far I've come to this:
SELECT FieldA FROM table
WHERE FieldB IN (12, 13) AND FieldB NOT IN (14)
But it doesn't seem to work, what am I missing ? Also, I would like to do it in a way that it is cross-database.
Upvotes: 2
Views: 152
Reputation: 1270191
This is an example of a "set-within-sets" subqueries. I like to handle these with group by
and having
, because this is a very flexible approach. Based on the question in the text:
SELECT FieldA
FROM table
GROUP BY FieldA
HAVING SUM(CASE WHEN FieldB = 12 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN FieldB = 14 THEN 1 ELSE 0 END) = 0;
Each condition in the having
clause is checking for one of the conditions you care about. The first counts the number of rows where FieldB = 12
and the > 0
makes sure there is at least one. The second counts the number of rows where FieldB = 14
. The = 0
makes sure there are none.
If, as suggested by your code, you want 12 and 13, then you can do:
SELECT FieldA
FROM table
GROUP BY FieldA
HAVING SUM(CASE WHEN FieldB = 12 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN FieldB = 13 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN FieldB = 14 THEN 1 ELSE 0 END) = 0;
And, if you want 12 or 13, you can do:
SELECT FieldA
FROM table
GROUP BY FieldA
HAVING SUM(CASE WHEN FieldB IN (12, 13) THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN FieldB = 14 THEN 1 ELSE 0 END) = 0;
Upvotes: 3