PostgreSQL 运算符:从入门到实战
在数据库的世界里,运算符就像是你手里的工具箱。当你需要对数据进行加减乘除、比较大小、判断真假,或者处理复杂的字符串和数组时,PostgreSQL 运算符就是你不可或缺的助手。它们让 SQL 查询不再只是“查数据”,而是真正能“处理数据”的强大语言。
如果你刚接触 PostgreSQL,或者已经在用它写查询但总觉得“差点意思”,那这篇关于 PostgreSQL 运算符的深度解析,或许正是你需要的。我们不会一上来就堆砌语法,而是从你最熟悉的场景出发,一步步带你理解这些“运算符”到底能做什么、怎么用,以及为什么它们如此重要。
基础运算符:算术与比较的基石
在所有编程语言中,算术运算符是最基础、最直观的一类。PostgreSQL 同样支持加(+)、减(-)、乘(*)、除(/)等基本运算。它们不仅可以用于数字,还能配合日期类型进行时间计算。
-- 示例:计算员工年薪(月薪 * 12)并加上奖金
SELECT
name,
salary * 12 + bonus AS annual_income
FROM employees;
注释:这里
salary * 12是乘法运算,将月薪乘以 12 得到年基本工资;+ bonus是加法,把奖金也加进去。最终结果命名为annual_income,方便后续使用。
再来看看比较运算符,它们是条件查询的核心。比如你想找出薪资高于 10000 的员工:
-- 示例:筛选薪资大于 10000 的员工
SELECT name, salary
FROM employees
WHERE salary > 10000;
注释:
>是大于运算符,用来判断salary是否大于 10000。返回所有符合条件的记录。类似地,<(小于)、>=(大于等于)、<=(小于等于)、=(等于)、<>或!=(不等于)也都是常用的比较操作。
小贴士:在 PostgreSQL 中,
!=和<>是等价的,都可以表示“不等于”,但推荐使用!=,更符合 SQL 标准。
逻辑运算符:让条件变得更灵活
当你要组合多个条件时,逻辑运算符就派上用场了。PostgreSQL 支持 AND、OR 和 NOT 三种逻辑操作,它们像“电路开关”一样,控制查询结果的流向。
比如,你想找“年薪超过 120000 且职位为经理”的员工:
-- 示例:使用 AND 组合多个条件
SELECT name, job_title, salary * 12 AS annual_salary
FROM employees
WHERE salary * 12 > 120000
AND job_title = '经理';
注释:
AND要求两个条件都为真才返回结果。如果薪资高但不是经理,或者职位是经理但年薪不够,都不会被选中。
再比如,想查“不是程序员也不是设计师”的员工:
-- 示例:使用 NOT 和 OR
SELECT name, job_title
FROM employees
WHERE NOT (job_title = '程序员' OR job_title = '设计师');
注释:
OR表示“或”的关系,括号内任一条件为真,整个表达式为真;NOT取反,因此最终结果是“既不是程序员也不是设计师”的人。
逻辑运算符的优先级是:NOT > AND > OR,所以括号在这里非常关键,避免歧义。
字符串运算符:文本处理的利器
在实际业务中,我们经常需要拼接字符串、判断子串是否存在,或者做模糊匹配。PostgreSQL 提供了强大的字符串操作能力。
最常用的字符串拼接是 || 操作符:
-- 示例:将姓名和职位合并成完整描述
SELECT
name || ' 是一名 ' || job_title AS description
FROM employees;
注释:
||是字符串连接符,将多个字符串按顺序拼接。输出如“张三 是一名 经理”。
此外,PostgreSQL 还支持正则表达式匹配,用 ~(匹配)和 ~*(不区分大小写匹配):
-- 示例:查找姓名中包含“小”字的员工
SELECT name, job_title
FROM employees
WHERE name ~ '小';
注释:
~是正则匹配操作符,'小'表示匹配任何包含“小”字的字符串。如果名字是“小李”、“王小明”,都会被查出来。
如果你想要忽略大小写,可以使用 ~*:
-- 示例:不区分大小写查找包含 "admin" 的用户名
SELECT username
FROM users
WHERE username ~* 'admin';
注释:
~*会自动忽略大小写,所以 "Admin"、"ADMIN"、"aDmIn" 都能匹配。
数组与 JSON 运算符:现代数据结构的处理
PostgreSQL 不只是关系型数据库,它对数组和 JSON 的支持也极为强大。这些运算符让你能轻松处理复杂数据结构。
创建数组与初始化
PostgreSQL 支持直接定义数组类型,并用 ARRAY[] 或 {} 来初始化:
-- 示例:创建一个包含分数的数组
SELECT
ARRAY[85, 92, 78, 96] AS scores,
ARRAY['apple', 'banana', 'cherry'] AS fruits;
注释:
ARRAY[]是创建数组的标准语法。这里分别创建了分数数组和水果数组。
数组元素访问与操作
你可以通过下标访问数组元素(从 1 开始):
-- 示例:获取数组第 2 个元素
SELECT
scores[2] AS second_score
FROM (
SELECT ARRAY[85, 92, 78, 96] AS scores
) t;
注释:
scores[2]表示取数组中第 2 个元素,这里是 92。注意 PostgreSQL 数组下标从 1 开始,不是 0。
还可以使用 @> 操作符判断一个数组是否包含另一个数组的所有元素:
-- 示例:判断是否包含所有指定科目
SELECT
ARRAY[1, 2, 3] @> ARRAY[2, 3] AS contains_all;
注释:
@>表示“包含”,ARRAY[1, 2, 3]包含ARRAY[2, 3]的所有元素,所以返回 true。
JSON 运算符:结构化数据的精准操作
PostgreSQL 对 JSON 支持非常完整,常用操作符包括 ->(提取对象字段)、->>(提取为文本)、?(检查键是否存在)等。
-- 示例:从 JSON 字段中提取信息
SELECT
data->'name' AS name,
data->'age' AS age,
data->>'city' AS city -- 注意:->> 返回文本
FROM users
WHERE data ? 'email'; -- 检查是否包含 email 键
注释:
->返回 JSON 类型,->>返回文本类型,适合直接展示。?用于判断 JSON 中是否存在某个键。
布尔运算符与空值处理:避免陷阱的关键
在写查询时,你可能会遇到 NULL 值带来的“陷阱”。比如 NULL = NULL 返回的是 UNKNOWN,而不是 TRUE,这容易导致逻辑错误。
PostgreSQL 提供了 IS NULL 和 IS NOT NULL 来正确判断空值:
-- 示例:筛选出邮箱为空的用户
SELECT name, email
FROM users
WHERE email IS NULL;
注释:不能用
email = NULL,因为NULL与任何值比较都不返回 true。必须使用IS NULL。
布尔类型本身也可以参与运算。例如,判断某个字段是否为真:
-- 示例:只显示 active 为 true 的用户
SELECT name, active
FROM users
WHERE active = TRUE;
注释:
TRUE和FALSE是 PostgreSQL 的布尔值,可以像数字一样参与条件判断。
实战案例:综合运用 PostgreSQL 运算符
我们来做一个完整的例子:统计所有年薪超过 10 万,且职位不是“实习生”的员工,且名字中包含“明”字。
-- 综合案例:多条件查询
SELECT
name,
job_title,
salary * 12 AS annual_salary,
CASE
WHEN salary * 12 > 120000 THEN '高薪'
ELSE '普通'
END AS salary_level
FROM employees
WHERE salary * 12 > 100000
AND job_title != '实习生'
AND name ~ '明';
注释:这里综合使用了算术运算符(
*)、比较运算符(>、!=)、字符串匹配运算符(~),以及CASE表达式做分类。最终结果清晰展示出符合条件的高薪员工。
结语
PostgreSQL 运算符远不止是“加减乘除”那么简单。它们是构建复杂、高效查询的基石,让你能够真正“处理”数据,而不仅仅是“查看”数据。
无论是基础的算术比较,还是高级的数组、JSON 操作,PostgreSQL 都提供了丰富而强大的工具。掌握这些运算符,不仅能让你的 SQL 更简洁,还能显著提升开发效率。
无论你是初学者,还是已有经验的开发者,建议在实际项目中多尝试使用这些运算符。在实践中理解它们的用法,才是最有效的学习方式。
当你下次写查询时,不妨多问一句:有没有更优雅的运算符能帮我简化逻辑?答案,往往就藏在 PostgreSQL 运算符的深处。