10 Expressions
An expression is anything PostgreSQL can evaluate to a single value: a literal, a column reference, an arithmetic operation, a function call, a CASE, even another SELECT that returns one value. Expressions can appear almost anywhere — in the select list, in WHERE, in ORDER BY, in GROUP BY, in index definitions. Mastering expressions is mastering SQL.
What you’ll learn
- Arithmetic, string, and boolean expressions
- Calling built-in functions in expressions
- Using expressions in
SELECT,WHERE, andORDER BY - Casting between types with
::andCAST(... AS ...) - Naming expression results with
AS
Example
The || operator concatenates strings. In PostgreSQL, if either operand is not text, it is coerced to text (so 'id_' || 5 works). +, -, *, /, % are the usual arithmetic operators; remember that integer division truncates toward zero.
PostgreSQL casts come in two flavors. value::type is the PostgreSQL-specific shortcut and is the common style. CAST(value AS type) is SQL-standard and reads better when the expression is complex. Both compile to the same thing.
Expressions in WHERE and ORDER BY are evaluated for every candidate row, which means a function call there can prevent index use. WHERE lower(email) = 'a@b.com' cannot use a plain index on email; it can use an expression index defined as CREATE INDEX ON users (lower(email)).
Run the example
To run:
Common pitfalls
- Integer division returning
0:1 / 2is0. Cast:1.0 / 2,1::numeric / 2, or usenumericcolumns. - Casting strings that don’t parse — e.g.
'abc'::integerraises an error. PostgreSQL is strict about types compared to MySQL. - Expressions returning different types in different branches of
CASEcause type-mismatch errors; cast to a common type. - Operators have precedence;
1 + 2 * 3is7. When in doubt, parenthesize.
When an expression is reused several times in one query, put it in a CTE or derived table once, instead of repeating it. PostgreSQL is smart enough to fold many duplicates, but the code stays cleaner.
Run SELECT id, name, id || ': ' || name AS label FROM fruits ORDER BY id LIMIT 3;. Then try SELECT name FROM fruits WHERE length(name) > 5;. Then cast: SELECT '3.14'::numeric * 2 AS doubled;.
Downloads
SQL file: expressions.sql · All lesson files · Setup guide