Skip to content

操作符优先级

什么是操作符优先级?

在SQL表达式中,当多个操作符一起使用时,数据库需要决定先执行哪个操作。操作符优先级就是决定这个执行顺序的规则。优先级高的操作符会先被执行。

想象一下计算 2 + 3 * 4 的过程:

  • 如果先计算 2 + 3 再乘以 4,结果是 20
  • 如果先计算 3 * 4 再加上 2,结果是 14

在数学和SQL中,乘法的优先级高于加法,所以正确答案是 14

为什么需要了解操作符优先级?

理解操作符优先级有助于:

  1. 编写准确的查询:避免因操作符执行顺序不符合预期而导致的错误结果
  2. 优化查询可读性:合理使用括号可以使查询逻辑更清晰
  3. 调试复杂表达式:当查询结果异常时,能够理解表达式的实际执行顺序

PostgreSQL操作符优先级表

下表展示了PostgreSQL中操作符的优先级顺序(从高到低)和结合方向:

优先级操作符/元素结合方向描述示例
1.表/列名称分隔符table.column
2::PostgreSQL类型转换value::integer
3[ ]数组元素选择array[1]
4+ -(一元)正负号-value, +value
5COLLATE排序规则column COLLATE "en_US"
6AT时区转换timestamp AT TIME ZONE 'UTC'
7^指数2^3 (= 8)
8* / %乘法、除法、取模10/2, 10*2, 10%3
9+ -(二元)加法、减法1+2, 3-1
10其他操作符其他内置和用户定义操作符各种自定义操作符
11BETWEEN IN LIKE ILIKE SIMILAR-范围、成员、字符串匹配a BETWEEN 1 AND 10, b IN (1,2,3)
12< > = <= >= <>-比较操作符a > b, x = y
13IS ISNULL NOTNULL-NULL值测试x IS NULL, y IS NOT NULL
14NOT逻辑非NOT condition
15AND逻辑与a AND b
16OR逻辑或a OR b

操作符优先级示例

示例1:算术操作符

sql
SELECT 2 + 3 * 4;  -- 结果是14,不是20

这里乘法 * 的优先级高于加法 +,所以先计算 3 * 4 = 12,然后 2 + 12 = 14

如果想要先执行加法,可以使用括号:

sql
SELECT (2 + 3) * 4;  -- 结果是20

示例2:逻辑操作符

sql
SELECT * FROM products 
WHERE price > 100 AND category = 'electronics' OR stock > 0;

在这个查询中,AND 的优先级高于 OR,所以条件解析为: (price > 100 AND category = 'electronics') OR stock > 0

如果想要不同的执行顺序,需要明确使用括号:

sql
SELECT * FROM products 
WHERE price > 100 AND (category = 'electronics' OR stock > 0);

示例3:复杂表达式

sql
SELECT 
    product_name,
    price * 0.9 AS discounted_price
FROM products
WHERE (price BETWEEN 50 AND 200) AND NOT is_discontinued;

这个查询中的优先级执行顺序:

  1. price BETWEEN 50 AND 200 作为一个整体评估
  2. NOT is_discontinued 中的 NOT 应用于 is_discontinued
  3. 两个条件用 AND 连接
  4. price * 0.9 的乘法在 SELECT 子句中计算

使用括号提高可读性

虽然了解操作符优先级很重要,但在编写复杂查询时,建议使用括号明确指定执行顺序,这样可以:

  • 提高代码可读性
  • 避免依赖优先级规则导致的错误
  • 使查询意图更加清晰

例如:

sql
-- 不使用括号(依赖默认优先级)
SELECT * FROM orders WHERE order_date > '2023-01-01' AND status = 'pending' OR status = 'processing';

-- 使用括号明确执行顺序(更清晰)
SELECT * FROM orders WHERE order_date > '2023-01-01' AND (status = 'pending' OR status = 'processing');

注意事项

  1. 用户定义的操作符会继承与同名内置操作符相同的优先级
  2. 使用 OPERATOR() 语法时,无论内部是什么操作符,都会使用默认优先级
  3. 当有疑问时,最好使用括号明确指定执行顺序

通过理解操作符优先级,您可以编写更准确、更可靠的SQL查询,并避免因执行顺序错误导致的意外结果。