
一、WHERE子句基础语法WHERE子句作用于FROM子句之后用于对查询结果集进行行级过滤。数据库引擎逐行评估WHERE条件表达式仅返回评估结果为TRUE的行。其标准语法结构如下SELECTcolumn1,column2FROMtable_nameWHEREcondition;在条件表达式中列名指定被评估的字段运算符定义比较逻辑值提供比较基准。多条件可通过AND、OR逻辑运算符组合括号用于显式指定评估优先级。执行时序WHERE子句的执行发生在GROUP BY聚合之前、FROM表扫描之后。理解这一执行序有助于编写正确且高效的查询。二、数据库环境构建为演示WHERE子句的各项功能先在MySQL中创建示例数据库并插入数据。CREATEDATABASEIFNOTEXISTSsql_learning;USEsql_learning;CREATETABLEwebsites(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,urlVARCHAR(200),alexaINT,countryVARCHAR(10));INSERTINTOwebsites(id,name,url,alexa,country)VALUES(1,Google,https://www.google.com/,1,USA),(2,淘宝,https://www.taobao.com/,13,CN),(3,菜鸟教程,http://www.runoob.com/,4689,CN),(4,微博,http://weibo.com/,20,CN),(5,Facebook,https://www.facebook.com/,3,USA);表结构说明列名类型说明idINT PK AUTO_INCREMENT自增主键确保行唯一性nameVARCHAR(50)网站名称urlVARCHAR(200)网站地址alexaINTAlexa排名数值countryVARCHAR(10)国家代码数据插入后形成五条样本记录涵盖中美两国网站排名数值跨度从1到4689可覆盖等值、范围、模式匹配等多种查询场景。三、文本值与数值的比较规则SQL中文本值与数值的语法处理存在严格区分类型书写方式示例文本值必须使用单引号包裹CN数值直接书写不加引号1混淆两类值的处理方式会引发隐式类型转换导致索引失效进而触发全表扫描。3.1 文本字段条件筛选country列的值为CN的所有记录SELECT*FROMwebsitesWHEREcountryCN;该查询对websites表全表扫描逐行比较country列值与字符串CN。满足条件的行包括id为2、3、4的三条记录。字符串比较的规则取决于列的字符集与排序规则——若采用utf8mb4_general_ci排序规则比较时不区分大小写。3.2 数值字段条件筛选id列的值为1的记录SELECT*FROMwebsitesWHEREid1;id列为主键且为整数类型数据库优化器可直接通过主键索引定位数据页执行效率远高于全表扫描。数值比较遵循数学等值规则不存在字符集或排序规则的影响。注意若将查询误写为WHERE id 1数据库需执行隐式转换将字符串1转为整数性能损耗在大数据量场景下显著。四、比较运算符的分类与应用WHERE子句支持六种基础比较运算符运算符含义适用类型等于所有类型/!不等于所有类型大于数值、字符串、日期小于数值、字符串、日期大于等于数值、字符串、日期小于等于数值、字符串、日期字符串比较依据字典序排列规则日期比较依据时间先后顺序。4.1 BETWEEN AND 范围查询筛选alexa排名在10到5000之间含两端的网站SELECT*FROMwebsitesWHEREalexaBETWEEN10AND5000;BETWEEN AND定义闭区间等价于alexa 10 AND alexa 5000。符合条件的记录idnamealexa2淘宝134微博203菜鸟教程4689注意事项❌ 下界值必须小于上界值若顺序颠倒BETWEEN 5000 AND 10则返回空结果集✅ 在数值类型列上BETWEEN可有效利用B树索引进行范围扫描执行计划中type通常显示为range。五、模式匹配与多值筛选5.1 LIKE 模糊查询LIKE运算符实现字符串模式匹配通配符含义%匹配零个或多个任意字符_匹配恰好一个任意字符筛选url以https开头的网站记录SELECT*FROMwebsitesWHEREurlLIKEhttps%;LIKE https%表示匹配以字符串https开头、后续为任意长度任意字符的url值。符合条件的记录Google和Facebook。性能考量模式以常量前缀开头如LIKE https%时索引条件下推特性可减少扫描行数模式以通配符开头如LIKE %google%时索引完全失效强制全表扫描。5.2 IN 多值匹配IN运算符用于多值离散匹配避免连续多个OR条件造成的语句冗余SELECT*FROMwebsitesWHEREcountryIN(USA,CN);IN括号内列出所有可接受的值各值以逗号分隔。数据库逐行检查country列值是否包含在值列表中。本示例中所有五条记录均满足条件。IN列表中的值数量建议控制在合理范围内。当值列表较大时可考虑将候选值存入临时表并通过JOIN实现等价筛选以获得更好的执行计划。六、NULL值的三值逻辑处理SQL采用三值逻辑TRUE / FALSE / UNKNOWN。NULL表示值未知或不存在。任何比较运算符与NULL比较的结果既非TRUE也非FALSE而是UNKNOWN。因此WHERE条件中NULL值行不会被返回必须使用IS NULL或IS NOT NULL专门判断。先插入一条包含NULL值的记录以演示INSERTINTOwebsites(id,name,url,alexa,country)VALUES(6,未知站点,NULL,NULL,NULL);正确写法SELECT*FROMwebsitesWHEREurlISNULL;该查询仅返回id为6的记录因为其url值为NULL。错误写法SELECT*FROMwebsitesWHEREurlNULL;-- 永远返回空结果集因为NULL NULL的评估结果为UNKNOWN而非TRUE。三值逻辑运算规则ANDTRUEFALSEUNKNOWNTRUETRUEFALSEUNKNOWNFALSEFALSEFALSEFALSEUNKNOWNUNKNOWNFALSEUNKNOWNORTRUEFALSEUNKNOWNTRUETRUETRUETRUEFALSETRUEFALSEUNKNOWNUNKNOWNTRUEUNKNOWNUNKNOWN理解三值逻辑运算规则是避免数据遗漏的关键。七、复合条件的逻辑组合7.1 运算符优先级多运算符混用时优先级NOTANDOR。使用括号可显式控制评估顺序增强可读性。7.2 AND 复合条件筛选country为CN且alexa小于100的网站SELECT*FROMwebsitesWHEREcountryCNANDalexa100;两个条件通过AND连接要求行必须同时满足。符合条件的记录idnamealexacountry2淘宝13CN4微博20CN优化建议数据库执行时优先评估选择性高的条件。若country列有索引而alexa列无索引优化器可能先通过country索引筛选再对alexa做行级过滤。复合条件编写时建议将高选择性条件前置。7.3 OR 复合条件筛选alexa小于20或country为USA的网站SELECT*FROMwebsitesWHEREalexa20ORcountryUSA;OR条件返回满足任一子条件的行。符合条件的记录Google、淘宝、Facebook。OR条件可能导致索引合并或转为全表扫描。对于OR条件较多且各条件涉及不同列的场景考虑改写为UNION查询以获得更优性能。八、WHERE与HAVING的功能边界维度WHEREHAVING执行阶段GROUP BY之前GROUP BY之后过滤对象原始行数据聚合后的分组结果聚合函数❌ 不可引用✅ 可引用如COUNT()、SUM()原始列✅ 可引用❌ 只能引用GROUP BY中的列8.1 聚合前过滤WHERE先筛选出CN国家的数据再按country分组统计网站数量SELECTcountry,COUNT(*)ASsite_countFROMwebsitesWHEREcountryCNGROUPBYcountry;WHERE子句在GROUP BY之前执行过滤掉非CN的行仅对三条CN记录进行分组统计。此写法比先分组再用HAVING过滤效率更高因为聚合操作的数据量被预先削减。8.2 聚合后过滤HAVING按country分组统计网站数量仅保留数量大于1的分组SELECTcountry,COUNT(*)ASsite_countFROMwebsitesGROUPBYcountryHAVINGCOUNT(*)1;HAVING COUNT(*) 1作用于分组后的聚合结果筛选出网站数量大于1的国家。此过滤逻辑无法用WHERE实现因为WHERE执行时尚无COUNT()聚合值。九、性能优化注意事项9.1 索引基础优化在WHERE筛选条件涉及的列上建立索引是基础优化手段。9.2 避免索引失效函数包装导致索引失效-- ❌ 不推荐函数包装导致索引失效触发全表扫描SELECT*FROMwebsitesWHEREUPPER(country)CN;-- ✅ 推荐直接比较以利用索引SELECT*FROMwebsitesWHEREcountryCN;若确实需要大小写不敏感匹配应在表设计阶段统一数据格式或使用大小写不敏感的排序规则而非在查询时进行函数转换。隐式类型转换同样破坏索引-- ❌ 触发列值隐式转换可能全表扫描SELECT*FROMwebsitesWHEREvarchar_column123;-- ✅ 保持类型一致SELECT*FROMwebsitesWHEREvarchar_column123;9.3 优化工作流程合理利用EXPLAIN命令分析执行计划验证索引是否按预期生效EXPLAINSELECT*FROMwebsitesWHEREcountryCN;关注执行计划中的type访问类型、key使用的索引、rows扫描行数三个关键指标。理想情况下type应为ref或rangekey不为NULLrows尽可能小。总结知识点核心内容WHERE语法SELECT ... FROM ... WHERE condition文本 vs 数值文本必须加引号数值不加引号比较运算符BETWEEN模式匹配LIKE%_通配符多值匹配IN (val1, val2, ...)NULL处理用IS NULL/IS NOT NULL不能用复合条件ANDORNOT括号控制优先级WHERE vs HAVINGWHERE过滤原始行聚合前HAVING过滤分组结果聚合后性能优化避免函数包装和隐式类型转换善用EXPLAIN