PostgreSQL 运算符

PostgreSQL 运算符完全指南

涵盖 算术、比较、逻辑、字符串、数组、JSON、范围、位运算、自定义 等全部类型,配 示例 + 性能提示 + 最佳实践


一、运算符总览

类型运算符示例
算术+ - * / % ^5 + 3
比较= > < >= <= <> !=age > 18
逻辑AND OR NOTactive AND age > 30
字符串|| LIKE ILIKE ~ ~* !~ !~*'a' || 'b'
数组@> <@ = &&tags @> '{dev}'
JSON-> ->> @> ? ?| ?& #> #>>profile ->> 'name'
范围@> <@ &&'[1,10]'::int4range @> 5
位运算& | # ^ ~ << >>5 & 3
NULLIS NULL IS NOT NULL IS DISTINCT FROMemail IS NULL

二、准备测试数据

CREATE TABLE demo (
    id SERIAL PRIMARY KEY,
    name TEXT,
    age INT,
    salary NUMERIC(10,2),
    tags TEXT[],
    config JSONB,
    score INT,
    active BOOLEAN,
    ip INET,
    period TSRANGE,
    bits INT
);

INSERT INTO demo (name, age, salary, tags, config, score, active, ip, period, bits)
VALUES 
('Alice', 25, 70000.00, '{"dev","lead"}', '{"level": 5, "theme": "dark"}', 95, true, '192.168.1.10', '[2025-01-01, 2025-12-31)', 5),
('Bob', 30, 50000.50, '{"hr"}', '{"level": 3}', 80, true, '192.168.1.20', '[2025-06-01, 2025-12-31)', 3),
('Carol', NULL, 80000.00, '{"dev","ai"}', '{"level": 6}', NULL, false, NULL, NULL, 7);

三、算术运算符

运算符说明示例结果
+5 + 38
-10 - 46
*6 * 742
/除(整数 → 整数)10 / 33
/除(浮点)10.0 / 33.333...
%取模10 % 31
^2 ^ 38
SELECT salary, salary * 1.1 AS bonus_10 FROM demo;

四、比较运算符

运算符说明示例
=等于age = 25
<> / !=不等于name <> 'Alice'
> / <大于 / 小于salary > 60000
>= / <=≥ / ≤score >= 90

注意NULL 比较返回 UNKNOWN,不会是 TRUE

-- 错误:不会匹配 NULL
SELECT * FROM demo WHERE score != 90;

-- 正确:用 IS NULL
SELECT * FROM demo WHERE score IS NULL;

五、逻辑运算符

运算符说明示例
ANDactive AND age > 25
ORage < 30 OR salary > 70000
NOTNOT active
SELECT * FROM demo 
WHERE (age > 25 OR salary > 70000) AND active;

六、字符串运算符

运算符说明示例结果
||拼接'Hello' || ' ' || 'World''Hello World'
LIKE模式匹配(大小写敏感)name LIKE 'A%'Alice
ILIKE忽略大小写name ILIKE 'a%'Alice
~正则匹配(大小写敏感)name ~ '^A'Alice
~*正则忽略大小写name ~* '^a'Alice
!~ / !~*正则不匹配name !~ 'bob'true
SELECT name || ' earns $' || salary AS info FROM demo;
SELECT * FROM demo WHERE name ILIKE '%a%';

七、数组运算符(Array)

运算符说明示例结果
@>包含tags @> '{"dev"}'Alice, Carol
<@被包含'{"dev"}' <@ tagsAlice, Carol
=相等tags = '{"dev","lead"}'Alice
&&重叠(有交集)tags && '{"ai"}'Carol
||拼接数组tags || '{"new"}'{"dev","lead","new"}
-- 包含 dev 和 lead
SELECT * FROM demo WHERE tags @> '{"dev","lead"}';

-- 添加标签
UPDATE demo SET tags = tags || '{"beta"}' WHERE name = 'Alice';

性能:数组列建议建 GIN 索引

CREATE INDEX idx_demo_tags ON demo USING GIN (tags);

八、JSON / JSONB 运算符(PostgreSQL 杀手级)

运算符说明示例结果
->按键取对象config -> 'level'{"level": 5}
->>按键取文本config ->> 'level''5'
#>按路径取对象config #> '{settings,theme}'"dark"
#>>按路径取文本config #>> '{settings,theme}''dark'
@>包含config @> '{"level": 5}'Alice
<@被包含'{"level": 5}' <@ configAlice
?键存在config ? 'level'true
?|, ?&任一/所有键存在config ?| '{level,theme}'true
-- 查询 level >= 5
SELECT name, (config ->> 'level')::INT AS level 
FROM demo 
WHERE (config ->> 'level')::INT >= 5;

-- 更新 JSON 字段
UPDATE demo SET config = jsonb_set(config, '{theme}', '"light"') WHERE name = 'Alice';

性能:JSONB 列建 GIN 索引

CREATE INDEX idx_demo_config ON demo USING GIN (config);

九、范围类型运算符(Range)

-- 查询包含 2025-06-01 的记录
SELECT * FROM demo WHERE period @> '2025-06-01'::date;

-- 两个时间段有交集
SELECT * FROM demo WHERE period && '[2025-07-01, 2025-08-01)'::tsrange;

十、位运算符(Bitwise)

运算符说明示例结果
&按位与5 & 31 (101 & 011 = 001)
|按位或5 | 37 (101
#按位异或5 # 36 (101 # 011 = 110)
~按位取反~5-6
<<左移1 << 24
>>右移8 >> 14
-- 权限系统:bit 1=读, 2=写, 4=删
SELECT * FROM demo WHERE (bits & 1) = 1;  -- 有读权限

十一、NULL 安全运算符

运算符说明示例结果
IS NULL是 NULLemail IS NULLCarol
IS NOT NULL非 NULLip IS NOT NULLAlice, Bob
IS DISTINCT FROMNULL 安全 ≠score IS DISTINCT FROM 90所有行
IS NOT DISTINCT FROMNULL 安全 =score IS NOT DISTINCT FROM NULLCarol
-- 传统写法(错误)
SELECT * FROM demo WHERE score != 90;  -- 跳过 NULL

-- 正确写法
SELECT * FROM demo WHERE score IS DISTINCT FROM 90;

十二、IN / NOT IN / ANY / ALL

-- IN
SELECT * FROM demo WHERE name IN ('Alice', 'Bob');

-- ANY (数组)
SELECT * FROM demo WHERE 'dev' = ANY(tags);

-- ALL (数组)
SELECT * FROM demo WHERE 'dev' = ALL(tags);  -- 所有元素都是 dev

-- 子查询
SELECT * FROM demo WHERE age > ANY (SELECT age FROM demo WHERE active);

十三、CASE 条件表达式(逻辑运算符)

SELECT name,
    CASE 
        WHEN salary > 70000 THEN 'High'
        WHEN salary > 50000 THEN 'Medium'
        ELSE 'Low'
    END AS salary_level
FROM demo;

十四、运算符优先级(从高到低)

1. :: [] . -> #> 
2. - (负号) ^ 
3. * / %
4. + -
5. IS, ISNULL, NOTNULL
6. (其他比较) BETWEEN IN LIKE ILIKE
7. NOT
8. AND
9. OR

() 明确优先级!


十五、自定义运算符(高级)

-- 创建加法运算符 !!
CREATE OR REPLACE FUNCTION add_int(a int, b int) RETURNS int AS $$
BEGIN RETURN a + b; END;
$$ LANGUAGE plpgsql;

CREATE OPERATOR !! (
    LEFTARG = int, RIGHTARG = int,
    PROCEDURE = add_int
);

-- 使用
SELECT 5 !! 3;  -- 结果 8

十六、最佳实践 Checklist

项目建议
NULL 安全IS NULL / IS DISTINCT FROM
数组/JSON@> + GIN 索引
字符串ILIKE 忽略大小写
性能避免 LIKE '%abc'(无法用索引)
可读性复杂条件用 ()
类型转换显式 ::int 避免隐式错误

十七、快速实战:5 分钟掌握核心运算符

-- 1. 字符串拼接 + 算术
SELECT name || ' earns $' || (salary * 1.1) AS bonus FROM demo;

-- 2. 数组包含 + JSON 提取
SELECT name, tags, config ->> 'level' AS level 
FROM demo 
WHERE tags @> '{"dev"}' AND (config ->> 'level')::INT > 4;

-- 3. NULL 安全 + 位运算
SELECT * FROM demo 
WHERE score IS DISTINCT FROM 90 
  AND (bits & 2) = 2;  -- 有写权限

-- 4. 范围包含
SELECT * FROM demo WHERE period @> CURRENT_DATE;

现在就动手
demo 表中:

  1. 查询 tags 包含 devsalary > 60000 的用户
  2. 更新 config.themelight(用 jsonb_set
  3. 查询 bits 有读权限(& 1)的用户
  4. 查询 period 包含今天的用户

需要我生成:

  • 100 条复杂测试数据?回复 测试数据
  • 权限系统位运算实战?回复 权限系统
  • JSON 嵌套查询高级用法?回复 JSON 高级
  • 自定义运算符实现 SQL 函数?回复 自定义运算符

随时告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注