恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
零基础学SQL 04:WHERE条件总写错?AND/OR/IN一图搞懂
首页
资讯中心
/
零基础学SQL 04:WHERE条件总写错?AND/OR/IN一图搞懂
零基础学SQL 04:WHERE条件总写错?AND/OR/IN一图搞懂
发布时间:2026/8/14 15:15:36
先说点真话当年做数据分析项目那会儿有回要给领导出一张技术部 销售部里工资超过 9000 的人的名单。新人交上来的 SQL 长这样WHERE部门技术部OR部门销售部AND工资9000结果查出来技术部所有人含工资 8000 的全在里头——因为AND优先级高于OR上面那句实际等于技术部全部或者销售部且工资9000。上报的数字直接错了挨了一顿批。这事儿让我记住WHERE不只会写单个条件条件一多优先级和写法就是坑。今天把AND/OR、IN、BETWEEN、LIKE一次讲透你写报表、做筛选再也不会被自己坑。 「SQL 从入门到精通」系列持续更新中关注我不迷路每篇都是实战干货。一、AND / OR多条件组合先搞清优先级你会什么场景下用到它你想同时卡好几个条件比如技术部且工资9000“北京或上海的客户”。这时候就要用AND并且和OR或者把条件拼起来。关键点AND比OR优先级高。就像乘法比加法先算一样。想改变顺序必须加括号()。正确写法加括号才是你真正想要的-- 意图只要技术部或销售部里工资9000 的人SELECT姓名,部门,工资FROM员工表WHERE(部门技术部OR部门销售部)AND工资9000;结果技术部 9000 不达标被排除销售部 9200 两人达标姓名部门工资王五销售部9200赵六销售部9200最大的坑不加括号时数据库按先 AND 后 OR算。下面这句和上面那句意思完全不同-- ❌ 实际含义技术部全部或销售部且工资9000WHERE部门技术部OR部门销售部AND工资9000记住口诀条件一多先想清楚我要的是哪一组然后用括号把那组括起来。宁可多写括号别信默认优先级。二、IN替代一长串 OR清爽又高效你会什么场景下用到它你想筛部门是技术部或销售部或市场部用OR要写三遍部门又长又难看-- 啰嗦写法WHERE部门技术部OR部门销售部OR部门市场部正确写法用IN一把梭SELECT姓名,部门FROM员工表WHERE部门IN(技术部,销售部,市场部);IN后面跟一个值列表等于等于其中任意一个。可读性高数据库也更容易优化。你后面学子查询时IN (SELECT ...)还能接一整张结果表非常常用。三、BETWEEN闭区间范围筛选你会什么场景下用到它你想筛工资在 8000 到 9500 之间包括 8000 和 9500 两端。正确写法SELECT姓名,工资FROM员工表WHERE工资BETWEEN8000AND9500;两个要点BETWEEN是闭区间包含两端8000 和 9500 都算。等价于工资 8000 AND 工资 9500但BETWEEN写起来更短语义更清楚。我当年踩的坑有人以为BETWEEN不含边界少算了临界值报表差了那么几个人。所以记住——BETWEEN两头都算。四、LIKE模糊查询找长得像的数据你会什么场景下用到它你记不全准确名字只想找姓张的“名字里带’小’的”“邮箱是 demo 结尾的”。精确等号匹配不了就要用LIKE做模糊匹配。两个通配符%代表任意长度0 个、1 个、多个字符_代表恰好 1 个字符正确写法-- 姓张的张开头后面任意SELECT姓名FROM员工表WHERE姓名LIKE张%;-- 名字里带小的小在任意位置SELECT姓名FROM用户表WHERE姓名LIKE%小%;-- 邮箱是 demo.com 结尾的SELECT邮箱FROM用户表WHERE邮箱LIKE%demo.com;-- 姓名恰好 2 个字、且姓张_ 占一个位置SELECT姓名FROM员工表WHERE姓名LIKE张_;我当年踩的坑性能在一张几千万行的大表里写LIKE %关键字%前面带%数据库没法用索引只能全表逐行扫查询直接超时。结论LIKE的通配符放前面前导通配会拖慢查询大表能避免就避免非要搜就尽量写成关键字%后缀匹配能用索引。五、当年我踩过的 3 个坑重点看AND/OR 不加括号统计口径错上面那个技术部或销售部且9000的例子少一对括号上报数字全错。结论多条件必加括号别赌默认优先级。以为 BETWEEN 不含边界漏算临界值报表人数差几个。结论BETWEEN闭区间两头都算。LIKE 前导通配符拖垮大表查询%x%让几千万行表全表扫描、查询超时。结论模糊查询尽量写成x%别在前面加%。六、3 个练习自己跑一遍基于下面的员工表和订单表查出工资在 9000 到 9500 之间的员工姓名和工资。查出部门是技术部或销售部且工资大于 9000 的员工。用 LIKE 查出姓名以王开头的员工。参考答案先自己写再对照-- 1SELECT姓名,工资FROM员工表WHERE工资BETWEEN9000AND9500;-- 2括号决定优先级SELECT姓名,部门,工资FROM员工表WHERE(部门技术部OR部门销售部)AND工资9000;-- 3SELECT姓名FROM员工表WHERE姓名LIKE王%;思考题练习 2 如果不加括号结果会变成什么为什么技术部工资 9000 的人会被算进来想明白这个AND/OR 优先级这关就过了。七、小结AND并且/OR或者组合条件AND优先级高于OR多条件必加括号。IN (值1, 值2, ...)替代一长串OR清爽高效后面还能接子查询。BETWEEN A AND B是闭区间包含 A 和 B 两端。LIKE模糊匹配%任意长度、_恰好一个前导通配%x%会拖慢大表查询尽量写成x%。互动时间站队投票你写WHERE时最常被哪块坑过我当年铁定选AND/OR 不加括号然后对着错数字发呆。是 ① AND/OR 优先级、② BETWEEN 边界、还是 ③ LIKE 慢查询评论区打 1/2/3我挑典型的下篇专门讲索引优化避坑 我是 Hello_world12131十年数据分析经验。这篇有用的话点个赞 收藏顺便关注我SQL 从入门到精通系列每周更新关注后不错过新篇。 系列目录置顶 相关推荐篇02 SELECT/FROM/WHERE篇03 ORDER BY/GROUP BY/HAVINGSQL 函数速查表 ⏭️ 下篇预告篇05 去重与分页 DISTINCT/LIMIT SQL 系列统一练习表复制即可运行可重复执行不会报表已存在本系列所有文章都基于下面这 4 张固定表。每张表先DROP再CREATE所以每读一篇文重新跑一次这个块都安全不用从新建表。DROPTABLEIFEXISTS员工表;CREATETABLE员工表(员工idINTPRIMARYKEY,姓名VARCHAR(20),部门VARCHAR(20),工资DECIMAL(10,2),邮箱VARCHAR(50),手机VARCHAR(20),入职日期DATE);INSERTINTO员工表(员工id,姓名,部门,工资,邮箱,手机,入职日期)VALUES(1,张三,技术部,9000.00,zhangsandemo.com,13800000001,2019-03-01),(2,李四,技术部,9000.00,lisidemo.com,13800000002,2020-07-15),(3,王五,销售部,9200.00,wangwudemo.com,13800000003,2018-01-10),(4,赵六,销售部,9200.00,zhaoliudemo.com,13800000004,2021-05-20);DROPTABLEIFEXISTS订单表;CREATETABLE订单表(订单idINTPRIMARYKEY,员工idINT,订单金额DECIMAL(10,2),下单时间DATETIME,付款时间DATETIME,状态VARCHAR(20));INSERTINTO订单表(订单id,员工id,订单金额,下单时间,付款时间,状态)VALUES(101,1,3000.00,2026-01-10 10:00:00,2026-01-10 10:05:00,已付款),(102,1,2500.00,2026-02-15 14:00:00,2026-02-15 14:10:00,已付款),(103,3,4000.00,2026-03-20 09:30:00,2026-03-20 09:40:00,已付款),(104,2,1500.00,2026-04-05 16:00:00,NULL,待付款);DROPTABLEIFEXISTS用户表;CREATETABLE用户表(用户idINTPRIMARYKEY,姓名VARCHAR(20),手机VARCHAR(20),邮箱VARCHAR(50),地址VARCHAR(100));INSERTINTO用户表(用户id,姓名,手机,邮箱,地址)VALUES(1,张三,13900000001,zhangsandemo.com,北京市朝阳区),(2,李四,13900000002,lisidemo.com,上海市浦东新区),(3,王五,13900000003,wangwudemo.com,广州市天河区);DROPTABLEIFEXISTS任务表;CREATETABLE任务表(任务idINTPRIMARYKEY,员工idINT,备注VARCHAR(100),状态VARCHAR(20));INSERTINTO任务表(任务id,员工id,备注,状态)VALUES(1,1,完成需求评审,已完成),(2,2,NULL,进行中),(3,3,修复线上bug,已完成),(4,4,NULL,待分配);