Skip to content
Reference/SQL SELECT Statement Syntax
Reference

SQL SELECT Statement Syntax

The shape of a query, the order you write its clauses, and the order the database actually runs them.

A SELECT query reads rows from one or more tables and returns a result set. You write the clauses in a fixed order, even though the database evaluates them in a different order.

Full shape
select   column_a, column_b, count(*)
from     some_table
where    column_a > 0          -- filter rows
group by column_a, column_b    -- collapse into groups
having   count(*) > 5          -- filter groups
order by count(*) desc         -- sort the result
limit    10                    -- keep the first N rows

Clauses

ClausePurpose
SELECTWhich columns or expressions to return.
FROMWhich table(s) to read, including joins.
WHEREKeep only rows that match a condition (before grouping).
GROUP BYCollapse rows into one row per group.
HAVINGKeep only groups that match a condition (after grouping).
ORDER BYSort the final result.
LIMITReturn at most N rows.

Logical evaluation order

Knowing this order explains a lot of beginner surprises. For example, it explains why you cannot use a SELECT alias in WHERE, but you can in ORDER BY.

  1. FROM / joins
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT (aliases are created here)
  6. ORDER BY
  7. LIMIT

Columns, aliases, and DISTINCT

Example
select distinct
       category_id,
       product_name as name,
       price * 0.9   as sale_price
from   products
order by sale_price desc

* returns every column. That is handy while exploring, but name the columns you need in real queries. DISTINCT removes duplicate rows from the result. AS renames a column in the output.

Dialect note

DuckDB lets you reference a SELECT alias in WHEREand GROUP BY as a convenience. Most other engines (Postgres, SQL Server) do not. Repeat the full expression there to stay portable.