1. 首页 > PostgreSQL教程 > 正文

PostgreSQL教程FG054-PG运算符优先级:避免计算错误的核心规则

本文档风哥主要介绍PostgreSQL教程054相关内容。风哥教程参考PostgreSQL官方文档Server Administration, SQL Language内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。

1. 运算符优先级表

PostgreSQL运算符优先级从高到低排列:

更多学习教程公众号风哥教程itpux_com更多视频教程www.fgedu.net.cn

记忆技巧:括号优先级最高,可以改变默认优先级。不确定时,使用括号明确优先级。

2. 算术运算符优先级

— 算术运算符优先级演示
SELECT
2 + 3 * 4 AS without_paren,
(2 + 3) * 4 AS with_paren,
10 – 2 * 3 AS mult_before_sub,
10 / 2 + 3 AS div_before_add,
10 / (2 + 3) AS paren_first,
2 ^ 3 * 2 AS power_before_mult,
2 ^ (3 * 2) AS paren_before_power;

执行结果:

without_paren | with_paren | mult_before_sub | div_before_add | paren_first | power_before_mult | paren_before_power
—————+————+—————–+—————-+————-+——————-+——————–
14 | 20 | 4 | 8 | 2 | 16 | 64
(1 row)
— 一元运算符优先级
SELECT
-5 + 3 AS unary_1,
-(5 + 3) AS unary_2,
@ -5 AS abs_result,
-5 * 3 AS unary_mult,
-(5 * 3) AS paren_mult;

执行结果:

unary_1 | unary_2 | abs_result | unary_mult | paren_mult
———+———+————+————+————
-2 | -8 | 5 | -15 | -15
(1 row)

3. 比较运算符优先级

— 比较运算符优先级
SELECT
5 > 3 AND 2 < 4 AS compare_and, 5 > 3 OR 2 > 4 AS compare_or,
5 BETWEEN 1 AND 10 AS between_result,
5 IN (1, 2, 3, 4, 5) AS in_result,
‘hello’ LIKE ‘h%’ AS like_result;

执行结果:

compare_and | compare_or | between_result | in_result | like_result
————-+————+—————-+———–+————-
t | t | t | t | t
(1 row)
— IS NULL优先级
SELECT
NULL IS NULL AS is_null,
NULL IS NOT NULL AS is_not_null,
NOT NULL IS NULL AS not_is_null,
(NOT NULL) IS NULL AS paren_not;

执行结果:

is_null | is_not_null | not_is_null | paren_not
———+————-+————-+———–
t | f | f | t
(1 row)

4. 逻辑运算符优先级

— 逻辑运算符优先级:NOT > AND > OR
SELECT
TRUE OR FALSE AND FALSE AS or_and,
(TRUE OR FALSE) AND FALSE AS paren_or_and,
NOT TRUE AND FALSE AS not_and,
NOT (TRUE AND FALSE) AS paren_not_and,
NOT TRUE OR TRUE AS not_or,
NOT (TRUE OR TRUE) AS paren_not_or;

执行结果:

学习交流加群风哥QQ113257174

or_and | paren_or_and | not_and | paren_not_and | not_or | paren_not_or
——–+————–+———+—————+——–+————–
t | f | f | t | t | f
(1 row)
重要规则:NOT优先级最高,AND次之,OR最低。在复杂条件中,AND会先于OR计算。

— 复杂逻辑表达式
SELECT
TRUE AND FALSE OR TRUE AS and_or,
TRUE AND (FALSE OR TRUE) AS and_paren_or,
NOT FALSE AND TRUE AS not_and,
NOT (FALSE AND TRUE) AS paren_not_and,
TRUE OR TRUE AND FALSE AS or_and_mix,
(TRUE OR TRUE) AND FALSE AS paren_or_and_mix;

执行结果:

and_or | and_paren_or | not_and | paren_not_and | or_and_mix | paren_or_and_mix
——–+————–+———+—————+————+——————
t | t | t | t | t | f
(1 row)

5. 混合表达式优先级

— 混合运算符优先级
SELECT
5 > 3 + 2 AS compare_arith,
(5 > 3) + 2 AS paren_compare,
10 * 2 > 15 AS arith_compare,
TRUE AND 5 > 3 AS logic_compare,
5 > 3 AND 2 < 4 OR 1 = 0 AS mixed_1, (5 > 3 AND 2 < 4) OR 1 = 0 AS mixed_2, 5 > 3 AND (2 < 4 OR 1 = 0) AS mixed_3;

执行结果:

学习交流加群风哥微信: itpux-com

compare_arith | paren_compare | arith_compare | logic_compare | mixed_1 | mixed_2 | mixed_3
—————+—————+—————+—————+———+———+———
f | 3 | t | t | t | t | t
(1 row)

6. 常见错误案例

6.1 条件判断错误

— 创建测试表
CREATE TABLE fgedu_priority_test (
id SERIAL PRIMARY KEY,
status VARCHAR(20),
amount NUMERIC(10, 2),
category VARCHAR(20)
);

INSERT INTO fgedu_priority_test (status, amount, category) VALUES
(‘active’, 100.00, ‘A’),
(‘active’, 200.00, ‘B’),
(‘inactive’, 150.00, ‘A’),
(‘pending’, 300.00, ‘C’),
(‘active’, 50.00, ‘A’);

— 错误写法:想要status=active且category=A或B
— 错误理解:status = ‘active’ AND category = ‘A’ OR category = ‘B’
SELECT id, status, amount, category
FROM fgedu_priority_test
WHERE status = ‘active’ AND category = ‘A’ OR category = ‘B’;

执行结果(错误结果):

id | status | amount | category
—-+———+———+———-
1 | active | 100.00 | A
2 | active | 200.00 | B
4 | pending | 300.00 | C
(3 rows)
— 正确写法:使用括号明确优先级
SELECT id, status, amount, category
FROM fgedu_priority_test
WHERE status = ‘active’ AND (category = ‘A’ OR category = ‘B’);

执行结果(正确结果):

id | status | amount | category
—-+———+———+———-
1 | active | 100.00 | A
2 | active | 200.00 | B
(2 rows)

6.2 NULL处理错误

— NULL比较错误
SELECT
NULL = NULL AS null_eq,
NULL IS NULL AS null_is,
NULL != NULL AS null_neq,
NULL IS DISTINCT FROM NULL AS null_distinct,
NOT NULL = NULL AS not_null_eq,
NOT (NULL IS NULL) AS not_null_is;

执行结果:

null_eq | null_is | null_neq | null_distinct | not_null_eq | not_null_is
———+———+———-+—————+————-+————-
| t | | f | | f
(1 row)

6.3 类型转换优先级

— 类型转换优先级
SELECT
‘123’::INTEGER + 456 AS cast_first,
‘123’ || 456 AS concat_auto,
‘123’::TEXT || 456 AS cast_text_concat,
(‘123’::INTEGER + 456)::TEXT AS calc_then_cast;

执行结果:

cast_first | concat_auto | cast_text_concat | calc_then_cast
————+————-+——————+—————-
579 | 123456 | 123456 | 579
(1 row)

7. 实战案例:条件表达式

— 复杂业务条件查询
SELECT
id,
status,
amount,
category,
CASE
WHEN status = ‘active’ AND (category = ‘A’ OR category = ‘B’) AND amount >= 100
THEN ‘高优先级’
WHEN status = ‘active’ AND category = ‘C’
THEN ‘中优先级’
WHEN status = ‘pending’ AND amount > 200
THEN ‘待处理高金额’
ELSE ‘普通’
END AS priority_level
FROM fgedu_priority_test
ORDER BY id;

执行结果:

id | status | amount | category | priority_level
—-+———-+———+———-+—————-
1 | active | 100.00 | A | 高优先级
2 | active | 200.00 | B | 高优先级
3 | inactive | 150.00 | A | 普通
4 | pending | 300.00 | C | 待处理高金额
5 | active | 50.00 | A | 普通
(5 rows)
— 使用括号确保正确逻辑
SELECT
id,
status,
amount,
category,
CASE
WHEN (status = ‘active’ OR status = ‘pending’)
AND (category IN (‘A’, ‘B’))
AND (amount >= 100 OR amount <= 50) THEN '特殊处理' ELSE '正常处理' END AS process_type FROM fgedu_priority_test ORDER BY id;

执行结果:

from oracle:www.itpux.com

id | status | amount | category | process_type
—-+———-+———+———-+————–
1 | active | 100.00 | A | 特殊处理
2 | active | 200.00 | B | 正常处理
3 | inactive | 150.00 | A | 正常处理
4 | pending | 300.00 | C | 正常处理
5 | active | 50.00 | A | 特殊处理
(5 rows)
— 清理测试表
DROP TABLE IF EXISTS fgedu_priority_test;

执行结果:

风哥提示:

DROP TABLE
最佳实践:

  • 不确定优先级时,使用括号明确表达
  • 复杂条件分解为多个简单条件
  • 使用CTE提高可读性
  • NULL比较使用IS NULL/IS NOT NULL
  • 测试复杂表达式时使用简单数据验证

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息