---
title: "WHERE clause"
description: "The WHERE clause filters rows in a SQL query based on a boolean condition, keeping only rows for which the condition evaluates to true."
canonical: "https://motherduck.com/glossary/where-clause/"
related:
  - title: "Query syntax | MotherDuck Docs"
    url: "https://motherduck.com/docs/sql-reference/duckdb-sql-reference/query-syntax/"
  - title: "SQL Golf: 5 SQL Tricks You Should (Probably) Never Use"
    url: "https://motherduck.com/blog/its-a-sql-golf-quackmas/"
  - title: "DuckLake Lakehouse: Getting Started to Going Fast | MotherDuck"
    url: "https://motherduck.com/videos/ducklake-lakehouse-getting-started/"
gated_asset:
  title: "DuckLake: The Lakehouse Table Format"
  url: "https://motherduck.com/lp/ducklake-lakehouse-table-format-book-full/"
---

# WHERE clause

> The WHERE clause filters rows in a SQL query based on a boolean condition, keeping only rows for which the condition evaluates to true.

## Overview
The `WHERE` clause restricts which rows a query returns by applying a boolean condition to each row before any grouping or aggregation happens. It is one of the most fundamental pieces of SQL: nearly every non-trivial `SELECT`, `UPDATE`, or `DELETE` statement includes one to narrow down a dataset.

`WHERE` operates on individual rows, evaluating the condition once per row coming out of the `FROM` clause (including any `JOIN`s). Rows where the condition evaluates to `TRUE` are kept; rows where it evaluates to `FALSE` or `NULL` (unknown) are discarded.

<glossary-callout guide="duckdb-cheatsheet-full" />

## Syntax and operators
A `WHERE` condition can combine comparison operators (`=`, `<>`, `<`, `>`, `<=`, `>=`), logical operators (`AND`, `OR`, `NOT`), and predicates like `IN`, `BETWEEN`, `LIKE`, `IS NULL`, and `EXISTS`:

```sql
SELECT order_id, customer_id, order_total
FROM orders
WHERE status = 'completed'
  AND order_total > 100
  AND order_date >= DATE '2026-01-01';
```

## Where it fits in query execution
Conceptually, SQL evaluates clauses in this order: `FROM` -> `WHERE` -> `GROUP BY` -> `HAVING` -> `SELECT` -> `ORDER BY` -> `LIMIT`. Because `WHERE` runs before grouping, it cannot reference aggregate functions such as `SUM()` or `COUNT()` -- use `HAVING` for that instead.

DuckDB relaxes one common annoyance here: a non-aggregate column alias defined in the `SELECT` list can be referenced directly in the `WHERE` clause of the same query, without wrapping the query in a subquery or CTE:

```sql
SELECT order_total * 1.08 AS total_with_tax
FROM orders
WHERE total_with_tax > 100;
```

DuckDB also supports the SELECT-less `FROM tbl WHERE ...` shorthand for quick, ad hoc filtering during exploration.

## Common patterns
`WHERE` clauses frequently use subqueries (`WHERE customer_id IN (SELECT ...)`), correlated conditions (`WHERE EXISTS (SELECT 1 FROM ... WHERE ...)`), and range checks (`WHERE amount BETWEEN 10 AND 100`).