sql 中where条件同时使用and和or注意事项
引言
sql的where查询条件同时使用and、or,注意使用括号括住查询条件,不然查询结果与预想的会不一样。
如下sql,自己本意想查询asset_status = 'SETTLED'、settle_date 为空,或者asset_status = 'SETTLED'、settle_type为空的数据。
结果查询结果当中,asset_status有overdue的数据,与预期不符。
SELECT * FROM acc_cus.cus_repay_summary WHERE project_no = 'BUWS10043190001' AND asset_status = 'SETTLED' AND settle_date IS NULL OR settle_type IS NULL;
做以下改进后,查询结果与预期一致。
SELECT due_bill_no FROM acc_cus.cus_repay_summary WHERE (settle_date IS NULL OR settle_type IS NULL) AND project_no = 'BUWS10043190001' AND asset_status = 'SETTLED';
原因
MySQL中,AND的执行优先级高于OR。也就是说,在没有小括号()的限制下,总是优先执行AND语句,再执行OR语句。
select * from table where 条件1 AND 条件2 OR 条件3;
等价于
select * from table where ( 条件1 AND 条件2 ) OR 条件3;
假设下表要查询 sex = 2 且年龄为17或18的人员信息
create table user_info( id int auto_increment primary key comment '主键id', name varchar(20) comment '姓名', sex tinyint comment '性别 1 男 2 女', age int comment '年龄', id_card varchar(20) comment '身份证号', create_time datetime comment '创建时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC comment '用户信息表'; insert into user_info(name, sex, age, id_card, create_time) values ('小明',1,18,null,now()), ('小红',2,16,null,now()), ('小张',1,17,null,now()), ('小花',1,18,null,now()), ('小李',2,16,null,now()), ('小王',1,17,null,now()), ('小白',2,17,null,now()), ('笑笑',1,17,null,now());
这样查询:
select * from user_info where sex = 2 and age = 17 or age = 18;
结果是:
上面的sql查询过程如下:
首先查询:select * from user_info where sex = 2 and age = 17;
然后查询:select * from user_info where age = 18;
所以查询结果当中有sex为1的数据。
修改成:
select * from user_info where sex = 2 and (age = 17 or age = 18);
查询结果
修改后的sql,先查询sex = 2
在此基础上再查询age = 17 or age = 18
小结
在使用MySQL时同时使用AND和OR需要注意以下几点:
- 优先级:在一个SQL语句中同时使用AND和OR时,AND优先级高于OR。因此,如果没有使用括号来明确优先级,AND操作符优先执行。
- 括号:为了避免模糊,建议使用括号来明确操作符的优先级。例如,(A AND B)OR(C AND D)。
- 计算:AND和OR在计算时具有不同的含义。AND表示两个条件同时满足,而OR表示两个条件中至少一个满足。因此,将它们混合使用可能会导致逻辑错误。
- 范围:当使用多个AND和OR时,需要确保每个条件都在正确的范围内。否则,您可能会得到不正确的结果。
- 索引:当同时使用AND和OR时,您需要确保所使用的列都有适当的索引。否则,查询可能会非常慢。
假设我们有一张students表格,其中包含学生的ID、姓名、年龄、性别、城市等字段。我们想要查询所有来自上海或南京,并且年龄在18岁至25岁之间的女性学生。我们可以这样写SQL语句:
SELECT * FROM students WHERE (city = '上海' OR city = '南京') AND gender = 'female' AND age BETWEEN 18 AND 25;
在这个例子中,我们同时使用了AND和OR操作符,并使用括号来明确优先级。首先,我们筛选出来自上海或南京的所有学生,然后从中筛选女性学生,并最后筛选年龄在18至25岁之间的学生。这可以确保我们得到的结果符合我们的要求。
需要注意的是,如果我们没有使用括号来明确优先级,从而产生歧义,可能会得到不正确的结果。例如,如果我们将AND操作符的优先级放在OR操作符之前:
SELECT * FROM students WHERE city = '上海' OR city = '南京' AND gender = 'female' AND age BETWEEN 18 AND 25;
那么这个查询将会返回上海和南京的所有学生中,女性学生和18至25岁之间的所有学生,无论他们是否满足其他条件。这是因为AND操作优先于OR操作,因此,我们需要使用括号明确操作符的优先级。
参考:https://blog.csdn.net/weixin_43846827/article/details/125083886
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2021-01-16 面试的经验
2021-01-16 管理的经验一