ANY & ALL
ANY and ALL let you compare a value against every value returned by a multi-row subquery, using ordinary comparison operators like =, >, <, >=, and <=. They are placed right before the subquery, and they change how the comparison behaves across the whole set of returned values. They are a frequent source of confusion, mostly because the plain-English meaning of "any" and "all" does not immediately map onto how they behave with > and <.
The Core Idea
Expression | Equivalent To | Meaning in Plain English |
|---|---|---|
|
| Equal to at least one value returned |
|
| Not equal to any value returned (NULL caveats apply, same as NOT IN) |
| Greater than the maximum | Greater than every value returned |
| Less than the minimum | Less than every value returned |
| Greater than the minimum | Greater than at least one value returned |
| Less than the maximum | Less than at least one value returned |
> means you have to beat the toughest competitor — the maximum — so it is equivalent to "greater than the maximum." ANY with a > only means you have to beat the easiest competitor — the minimum — so it is equivalent to "greater than the minimum." The comparisons flip for <.= ANY: Equivalent to IN
-- These two queries return exactly the same result SELECT product_name FROM products WHERE category_id = ANY ( SELECT category_id FROM categories WHERE is_featured = true ); SELECT product_name FROM products WHERE category_id IN ( SELECT category_id FROM categories WHERE is_featured = true );
> ALL: Greater Than Every Value (the Maximum)
-- Employees who earn more than every employee in the Sales department -- i.e. more than the HIGHEST salary in Sales SELECT employee_name, salary FROM employees WHERE salary > ALL ( SELECT salary FROM employees WHERE department = 'Sales' ); -- Equivalent, written with a scalar subquery and MAX SELECT employee_name, salary FROM employees WHERE salary > ( SELECT MAX(salary) FROM employees WHERE department = 'Sales' );
> ANY: Greater Than at Least One Value (the Minimum)
-- Employees who earn more than AT LEAST ONE employee in Sales -- i.e. more than the LOWEST salary in Sales SELECT employee_name, salary FROM employees WHERE salary > ANY ( SELECT salary FROM employees WHERE department = 'Sales' ); -- Equivalent, written with a scalar subquery and MIN SELECT employee_name, salary FROM employees WHERE salary > ( SELECT MIN(salary) FROM employees WHERE department = 'Sales' );
Putting Them Side by Side
Suppose the Sales department has salaries of 40000, 55000, and 70000. Comparing an outside employee's salary against that set with ANY and ALL produces very different cutoffs:
-- Sales salaries: 40000, 55000, 70000 -- salary > ALL (...) --> must exceed 70000 (the maximum) -- salary > ANY (...) --> must exceed just 40000 (the minimum) -- salary < ALL (...) --> must be below 40000 (the minimum) -- salary < ANY (...) --> must be below just 70000 (the maximum)
NOT IN vs <> ALL
<> ALL (subquery) behaves the same as NOT IN (subquery), which means it carries the exact same NULL pitfall discussed on the EXISTS page — if the subquery returns even one NULL value, the comparison against every row becomes unknown, and the whole condition effectively excludes everything. NOT EXISTS remains the safer alternative when NULLs are possible.= ANYbehaves exactly likeIN— true if the value matches at least one row.<> ALLbehaves exactly likeNOT IN— including its NULL pitfall.> ALL/< ALLcompare against the toughest value (max / min respectively).> ANY/< ANYcompare against the easiest value (min / max respectively).When in doubt, rewrite ANY/ALL using MIN/MAX in a scalar subquery to double-check your logic.