10 表达式
表达式就是 PostgreSQL 能够求值为单个值的任何内容:字面量、列引用、算术运算、函数调用、CASE,甚至另一个返回单个值的 SELECT。表达式几乎无处不在:选择列表、WHERE、ORDER BY、GROUP BY 和索引定义中都能使用。掌握表达式,也就掌握了 SQL。
本章要点
- 算术、字符串和布尔表达式
- 在表达式中调用内置函数
- 在
SELECT、WHERE和ORDER BY中使用表达式 - 用
::和CAST(... AS ...)做类型转换 - 用
AS为表达式结果命名
示例
|| 操作符用于拼接字符串。在 PostgreSQL 中,如果任一操作数不是 text 类型,就会将其转换为 text(所以 'id_' || 5 可以运行)。+、-、*、/、% 是常见的算术操作符;记住,整数除法会向零截断。
PostgreSQL 的类型转换有两种写法。value::type 是 PostgreSQL 特有的简写,也是常用写法。CAST(value AS type) 属于 SQL 标准,表达式复杂时读起来更清楚。两种写法最终表达的是同一种类型转换。
WHERE 和 ORDER BY 中的表达式会对每个候选行求值,因此在这里调用函数可能会妨碍使用索引。WHERE lower(email) = 'a@b.com' 无法使用 email 上的普通索引,但如果定义了 CREATE INDEX ON users (lower(email)) 这样的表达式索引,就可以使用它。
运行示例
运行方式:
常见陷阱
- 整数除法返回
0:1 / 2的结果是0。可以改用非整数类型:1.0 / 2、1::numeric / 2,或使用numeric类型的列。 - 对无法解析的字符串做类型转换,例如
'abc'::integer,会报错。与 MySQL 相比,PostgreSQL 对类型的要求更严格。 - 如果表达式在
CASE的不同分支中返回不同类型,就会引发类型不匹配错误;应转换为共同类型。(译注:不同类型并不一定报错;若能按类型解析规则隐式转换为共同类型,表达式仍可成立。) - 操作符具有优先级:
1 + 2 * 3的结果是7。拿不准时就加括号。
如果同一个表达式在一条查询中重复使用多次,就把它放进公用表表达式(CTE)或派生表中,只写一次,避免重复。PostgreSQL 也能折叠许多重复的表达式,不过这样写代码还是更整洁。
运行 SELECT id, name, id || ': ' || name AS label FROM fruits ORDER BY id LIMIT 3;。然后尝试 SELECT name FROM fruits WHERE length(name) > 5;。最后做类型转换:SELECT '3.14'::numeric * 2 AS doubled;。
下载
SQL 文件: expressions.sql · 全部示例文件 · 准备工作