WHERE Clause
WHERE filters rows: given a candidate row, its condition evaluates to true, false, or unknown (when NULL is involved), and only rows where it evaluates to true are kept. It is the single most commonly used clause after SELECT itself, and it works the same way across SELECT, UPDATE, and DELETE.
Basic filtering
Rows matching a single condition
SELECT sku, name, stock_qty FROM products WHERE stock_qty < 20;
sku | name | stock_qty ----------+---------------+----------- SKU-1004 | Laptop Stand | 8
Combining conditions
More than one condition can be combined with AND, OR, and NOT to express more specific filters. The full set of comparison, logical, and pattern-matching operators available inside a WHERE clause is large enough to deserve its own page — see the Operators page for the complete map.
Combining conditions with AND / OR
SELECT sku, name, unit_price, stock_qty FROM products WHERE stock_qty < 20 AND (unit_price > 50 OR name ILIKE '%stand%');
WHERE and the logical execution order
WHERE runs early in a query's conceptual execution — right after the source rows are identified in FROM, and before any grouping happens. That ordering has a direct consequence: WHERE can only see and filter individual rows, never the results of an aggregate like COUNT(*) or SUM(...), because those aggregates have not been computed yet at the point WHERE runs.
This does NOT work — aggregates are not available yet in WHERE
SELECT customer_id, COUNT(*) AS order_count FROM orders WHERE COUNT(*) > 5 -- invalid: WHERE runs before GROUP BY / aggregation GROUP BY customer_id;
ERROR: aggregate functions are not allowed in WHERE
WHERE filters individual rows based on a boolean condition.
Multiple conditions combine with AND, OR, and NOT.
WHERE runs before GROUP BY, so it cannot reference aggregate functions.
HAVING is the equivalent tool for filtering after grouping, covered on its own page.