在SQL查询的WHERE子句中,当我们需要同时组合多个筛选条件时,逻辑运算符的优先级会直接影响最终的筛选结果。如果不主动用括号明确优先级,数据库会按照默认规则执行条件判断,很容易出现和预期不符的情况。

SQL逻辑运算符的默认优先级
SQL中常见的逻辑运算符包括AND、OR、NOT,它们的默认优先级从高到低依次是:NOT > AND > OR。也就是说,在没有括号的情况下,数据库会先执行NOT条件的判断,再执行AND条件的判断,最后执行OR条件的判断。
举个例子,如果我们要筛选年龄大于18岁且是男性,或者年龄大于60岁的用户,错误的写法可能会写成这样:
SELECT * FROM user_info WHERE age > 18 AND gender = '男' OR age > 60;
按照默认优先级,数据库会先执行age > 18 AND gender = '男'的判断,再执行OR age > 60的判断,这个例子的结果刚好符合预期。但如果需求是筛选年龄大于18岁,且是男性或者年龄大于60岁的用户,同样的写法就会出错,因为默认优先级下AND会先和前面的条件组合,不会先执行gender = '男' OR age > 60。
使用括号明确优先级的正确方法
当筛选逻辑比较复杂,包含多个AND和OR组合时,无论默认优先级是否符合预期,都建议用括号把需要优先执行的条件组合括起来,这样可以让逻辑更清晰,也避免后续修改条件时出现优先级混乱的问题。
场景一:OR条件需要优先执行
假设需求是查询部门为技术部,且工资大于10000或者工龄大于5年的员工,这时候需要让工资大于10000和工龄大于5年先组合,再和部门条件做AND判断,写法如下:
SELECT * FROM employee WHERE dept = '技术部' AND (salary > 10000 OR work_years > 5);
如果不加括号,按照默认优先级,会先执行dept = '技术部' AND salary > 10000,再执行OR work_years > 5,这样就会把其他部门工龄大于5年的员工也查询出来,不符合需求。
场景二:多层级逻辑组合
如果筛选逻辑更复杂,比如查询状态为正常,且(类型是A且价格小于100,或者类型是B且库存大于50)的商品,这时候可以用多层括号明确优先级:
SELECT * FROM goods
WHERE status = '正常'
AND (
(type = 'A' AND price < 100)
OR
(type = 'B' AND stock > 50)
);
这种写法把所有需要优先组合的条件都用括号明确标出,逻辑层级非常清晰,后续维护的时候也能快速看懂筛选规则,不容易出错。
括号使用的注意事项
- 括号必须成对出现,避免出现语法错误,编写完成后可以检查左右括号数量是否一致。
- 即使默认优先级符合需求,也建议加上括号,提升代码的可读性,方便其他开发者理解逻辑。
- 不要在括号内部写无关的自然语言注释,代码注释可以放在括号外部,或者用SQL的注释语法写在对应行末尾。
常见错误案例对比
下面通过表格对比错误写法和正确写法的差异:
| 需求描述 | 错误写法 | 正确写法 | 错误原因 |
|---|---|---|---|
| 查询北京或上海的用户,且注册时间在今年之后 | SELECT * FROM user WHERE city='北京' OR city='上海' AND reg_time > '2024-01-01' | SELECT * FROM user WHERE (city='北京' OR city='上海') AND reg_time > '2024-01-01' | 默认优先级下AND先执行,会查询上海且注册时间符合要求的用户,以及北京所有用户 |
| 查询成绩大于80分,且是数学或英语科目不及格的学生 | SELECT * FROM score WHERE score > 80 AND subject='数学' OR subject='英语' AND score < 60 | SELECT * FROM score WHERE score > 80 AND (subject='数学' OR subject='英语') AND score < 60 | 错误写法会查询数学80分以上,或者英语60分以下的学生,不符合需求 |
总的来说,在SQL中处理复杂逻辑筛选时,主动用括号明确优先级是最稳妥的做法,既可以保证查询结果符合预期,也能提升代码的可读性和可维护性,减少后续修改时出现逻辑错误的概率。