Hook: Interviewers love ALL because it looks simple, but one tiny detail — especially the empty-set case — separates memorized syntax from real understanding.
Question: What does ALL mean in SQL?
Answer: ALL is a quantified comparison operator. It means the comparison must be true for every value returned by a subquery, such as > ALL (...) or = ALL (...). If the subquery returns no rows, the condition is usually treated as true, because there is no row that breaks the rule.
Interview-Ready Answer: In SQL, ALL means “this comparison must hold for every value from the subquery.” So x > ALL (subquery) means x is greater than every returned value. A key detail is that if the subquery is empty, the condition evaluates to true, which is a classic interview gotcha.
ALL really doesDetailed Explanation: Think of ALL as a universal check: every row must pass. It appears after a comparison operator, not by itself, so you write patterns like > ALL, <= ALL, or = ALL. The database compares the left-hand value against each row produced by the subquery and only returns TRUE if none of those comparisons fail.
ALL condition becomes false.ALL is true.ANY / SOMEANY (also spelled SOME in standard SQL) is the opposite style: only one matching row is enough. That means ALL is a “every row” test, while ANY is an “at least one row” test.
| Construct | Meaning | Empty subquery | Typical use |
|---|---|---|---|
> ALL | Greater than every value | TRUE | Find values above the max |
> ANY | Greater than at least one value | FALSE | Find values above the min |
IN | Equal to one of the values | FALSE | Membership test |
ALL is useful when your business rule is naturally universal: “salary must be higher than every salary in a department,” “score must be at least as high as all minimum thresholds,” or “a product must beat all competitor prices.” It is often clearer than rewriting the same logic with nested aggregates, especially when you want to express the rule directly.
MAX or MIN when that is logically safe.> ALL, the database only needs the maximum subquery value to decide the result, so a good optimizer can reduce work.In big-O terms, a naive evaluation is O(n) over the subquery rows, with O(1) extra memory if rows are streamed. In practice, cost is usually dominated by how quickly the subquery can be filtered and whether the planner can rewrite it. For a small lookup table, the difference is tiny; for millions of rows, indexes and statistics matter a lot.
x > ALL (empty set) is true.NULL values: NULL can make the result unknown, not true or false, because SQL uses three-valued logic. If the subquery returns only NULLs, the comparison often becomes UNKNOWN.= ALL is strict: it means every returned value must equal the left side. If the subquery can return two different values, this becomes false.Memory Hook: Think “ALL = every apple in the basket.” One bad apple ruins the condition; an empty basket counts as not spoiled.
For > ALL (subquery), many candidates mentally translate it to “greater than the maximum value,” and that works when the subquery is non-empty and non-NULL. For < ALL, think “less than the minimum.” Just remember the empty-set and NULL rules, because that is where interviews get tricky.
Real-World Example: Imagine a checkout service that stores discounts approved by regional managers. A pricing rule might say: “A flash-sale price can go live only if it is below all approved competitor prices for that region.” That is a natural < ALL rule.
What goes wrong when someone misunderstands it? They might use ANY instead of ALL, which lets the sale price pass if it beats just one competitor instead of every competitor. In production, you would see bad price drops, support tickets about incorrect charges, and logs showing valid-looking query results that still violate the business rule. The bug is dangerous because the SQL returns rows — just not the right ones.
Another classic failure is forgetting the empty-set behavior. If the competitor table is temporarily empty for a region, < ALL becomes true, and a new price may be approved when the intended behavior was “block until data exists.” That kind of issue shows up as sudden approvals in the logs during a feed outage, not as a syntax error.
-- PostgreSQL-flavored SQL: runnable as a single script.
-- Demonstrates ALL, the empty-set rule, and a NULL gotcha.
DROP TABLE IF EXISTS employees;
DROP TABLE IF EXISTS dept_budgets;
DROP TABLE IF EXISTS thresholds;
CREATE TEMP TABLE employees (
emp_id INT PRIMARY KEY,
dept TEXT NOT NULL,
salary INT
);
CREATE TEMP TABLE dept_budgets (
dept TEXT PRIMARY KEY,
max_sal INT NOT NULL
);
CREATE TEMP TABLE thresholds (
value INT
);
INSERT INTO employees (emp_id, dept, salary) VALUES
(1, 'sales', 90000),
(2, 'sales', 110000),
(3, 'eng', 140000),
(4, 'eng', 155000),
(5, 'hr', NULL); -- edge case: NULL salary
INSERT INTO dept_budgets (dept, max_sal) VALUES
('sales', 100000),
('eng', 160000);
INSERT INTO thresholds (value) VALUES
(100),
(120),
(140),
(NULL); -- edge case: NULL in the subquery changes truth value
-- 1) Find employees whose salary is greater than ALL sales salaries.
-- This means salary > the maximum sales salary, not just one sales salary.
SELECT emp_id, dept, salary
FROM employees
WHERE salary > ALL (
SELECT salary
FROM employees
WHERE dept = 'sales'
AND salary IS NOT NULL
);
-- 2) Equivalent business rule expressed against a budget table.
-- Here, the row from 'eng' is allowed only if it is below every budget row for the same dept.
SELECT e.emp_id, e.dept, e.salary
FROM employees e
WHERE e.salary <= ALL (
SELECT max_sal
FROM dept_budgets b
WHERE b.dept = e.dept
);
-- 3) Empty-set edge case: the subquery returns no rows, so ALL is TRUE.
-- This often surprises people who expect FALSE.
SELECT
999 AS test_value,
999 > ALL (
SELECT value
FROM thresholds
WHERE value > 1000
) AS all_over_empty_set;
-- 4) NULL gotcha: a NULL in the subquery can make the result UNKNOWN.
-- In a WHERE clause, UNKNOWN behaves like FALSE, so the row is filtered out.
SELECT
150 > ALL (SELECT value FROM thresholds) AS comparison_with_null;
-- 5) If you want a safe version, exclude NULLs explicitly.
SELECT
150 > ALL (
SELECT value
FROM thresholds
WHERE value IS NOT NULL
) AS comparison_without_null;
-- 6) A useful contrast: ANY means "at least one" rather than "every one".
SELECT
150 > ANY (
SELECT value
FROM thresholds
WHERE value IS NOT NULL
) AS any_comparison;
Follow-up & Tricky Questions:
ALL different from ANY? ALL requires every comparison to be true; ANY requires at least one. A good shortcut is “all = every, any = one.”NULLs affect ALL? NULL can turn the result into UNKNOWN. In a WHERE clause, UNKNOWN acts like false, so you usually filter NULLs out if they are not meaningful.> ALL (subquery) be rewritten? Yes, often as a comparison with MAX when the subquery is known to be non-empty and non-NULL. The optimizer may do this automatically, but only when it is logically safe.= ALL the same as IN? No. IN means “matches at least one value,” while = ALL means “matches every value,” which is much stricter and often false if the subquery returns multiple different rows.x > ALL (subquery) the same as x > MAX(subquery)? Usually only when the subquery is guaranteed to return at least one non-NULL value. Without that guarantee, the empty-set and NULL behavior is different.x < ALL (subquery) mean smaller than all rows or smaller than any row? Smaller than all rows. Candidates often reverse this in their head; the word ALL is the clue.NULL, is the result always false? No. It is often UNKNOWN, which is different from false in SQL’s three-valued logic.Common Mistakes:
ANY when you mean ALL — correction: ask whether one match is enough or every row must pass.ALL over no rows is true.NULLs — correction: filter them out when they should not participate in the comparison.MAX or MIN too quickly — correction: only do that when the subquery cannot be empty and cannot contain meaningful NULLs.Memory Hook: “ALL = every apple must be good.” If one apple is bad, the basket fails; if the basket is empty, SQL says there is no bad apple, so it passes.
Cheat Sheet:
ALL = universal comparison: every row must satisfy the condition.> ALL often feels like “greater than the maximum.”< ALL often feels like “less than the minimum.”ALL returns true.NULL can produce UNKNOWN; filter it out when needed.ANY is the opposite style: one match is enough.Practice Tasks:
ALL competitor prices in the same category.MAX and compare the results when the competitor set is empty.NULL into the competitor prices and observe how the result changes before and after filtering NULLs.