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;
执行结果:
—————+————+—————–+—————-+————-+——————-+——————–
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;
执行结果:
———+———+————+————+————
-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;
执行结果:
————-+————+—————-+———–+————-
t | t | t | t | t
(1 row)
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;
执行结果:
———+————-+————-+———–
t | f | f | t
(1 row)
4. 逻辑运算符优先级
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
——–+————–+———+—————+——–+————–
t | f | f | t | t | f
(1 row)
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;
执行结果:
——–+————–+———+—————+————+——————
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
—————+—————+—————+—————+———+———+———
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’;
执行结果(错误结果):
—-+———+———+———-
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’);
执行结果(正确结果):
—-+———+———+———-
1 | active | 100.00 | A
2 | active | 200.00 | B
(2 rows)
6.2 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;
执行结果:
———+———+———-+—————+————-+————-
| 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;
执行结果:
————+————-+——————+—————-
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;
执行结果:
—-+———-+———+———-+—————-
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
—-+———-+———+———-+————–
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;
执行结果:
风哥提示:
- 不确定优先级时,使用括号明确表达
- 复杂条件分解为多个简单条件
- 使用CTE提高可读性
- NULL比较使用IS NULL/IS NOT NULL
- 测试复杂表达式时使用简单数据验证
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
