“Column Does Not Exist” — Using a SQL Alias in WHERE
In logical order, WHERE comes before SELECT assigns aliases, so many engines reject the alias there.
- PostgreSQL
-
column "margin" does not exist - SQL Server
-
Invalid column name 'margin'. - MySQL
-
Unknown column 'margin' in 'where clause' - SQLite
-
No error - SQLite also resolves the alias in WHERE.Checked on SQLite 3.53. Like DuckDB, it looks the name up in the SELECT list when no column matches.
- DuckDB
-
No error - the alias resolves in WHERE.A convenience DuckDB allows and most engines do not, which is what makes this a portability trap rather than a bug.
The symptom
You create a calculated column with as, then try to filter on
that alias in WHERE. In many databases, the query is rejected
with an error like "column not found" or
"referenced column does not exist".
select product_name,
price - cost as margin
from products
where margin > 10 Why it happens
SQL does not evaluate clauses from top to bottom as written.
WHERE filters rows before the SELECT list creates
output aliases, so portable SQL should not depend on margin
existing when the filter runs. The full sequence is on
SQL order of execution.
DuckDB, which powers SQLShed, allows this alias as a convenience, and so does SQLite. PostgreSQL, SQL Server, and MySQL do not. Treat the pattern as a portability trap, not a habit to build.
The fix
Either repeat the expression in WHERE, or compute it in a CTE
or subquery and filter in the outer query. Repeating is fine for short
expressions. A CTE is clearer when the calculation is longer or reused.
select product_name,
price - cost as margin
from products
where price - cost > 10 with product_margins as (
select product_name,
price - cost as margin
from products
)
select product_name, margin
from product_margins
where margin > 10
Most databases let ORDER BY use a SELECT alias because ordering
happens after the SELECT list is available. That exception does not apply to
WHERE in portable SQL.
How other engines word it
| Engine | Message |
|---|---|
| PostgreSQL | column "margin" does not exist |
| SQL Server | Invalid column name 'margin'. |
| MySQL | Unknown column 'margin' in 'where clause' |
| SQLite | No error - SQLite also resolves the alias in WHERE. Checked on SQLite 3.53. Like DuckDB, it looks the name up in the SELECT list when no column matches. |
| DuckDB | No error - the alias resolves in WHERE. A convenience DuckDB allows and most engines do not, which is what makes this a portability trap rather than a bug. |
Related errors
- Fix “Window Functions Are Not Allowed in WHERE” in SQL
Window functions are evaluated after WHERE, so you cannot filter on one directly.
- Fix “Aggregate Functions Are Not Allowed in WHERE” in SQL
WHERE filters rows before grouping, so aggregates do not exist yet. Use HAVING.
- Fix “Referenced Column Not Found” in SQL
No table in the FROM clause has a column by that name. Usually a typo or a table you did not join.
Learn more
Related
Understand tables, rows, columns, and queries.
Clause order and the shape of a SELECT query.
SELECT, WHERE, ORDER BY, and LIMIT at a glance.
Practice WITH clauses and step-by-step reports.
One-to-many joins can inflate totals.
Learn the basic shape of relational data.