Assuming no need for correlation, use:
SELECT a.*
FROM A a
WHERE EXISTS(SELECT NULL
FROM B b
HAVING MIN(b.some_val) > a.val)
If you do need correlation:
SELECT a.*
FROM A a
WHERE EXISTS(SELECT NULL
FROM B b
WHERE b.id = a.id
HAVING MIN(b.some_val) > a.val)
Explanation
The EXISTS
evaluates on a boolean, based on the first match - this makes it faster than say using IN, and -- unlike using a JOIN -- will not duplicate rows. The SELECT portion doesn't matter - you can change it to EXISTS SELECT 1/0 ...
and the query will still work though there's an obvious division by zero error.
The subquery within the EXISTS
uses the aggregate function MIN to get the smallest B.some_val - if that value is larger than the a.val value, the a.val is smaller than all of the b values. The only need for a WHERE
clause is for correlation - aggregate functions can only be used in the HAVING
clause.