当前位置: 首页 > news >正文

2.17 sql条件筛选(WHERE、比较运算符、逻辑运算符、BETWEEN、IN、LIKE模糊查询、IS NULL)

2.17 条件筛选(WHERE、比较运算符、逻辑运算符、BETWEEN、IN、LIKE模糊查询、IS NULL)

在电商数据分析中,你几乎不会查全表数据,永远是在筛选特定范围:

  • 只看某天的订单。

  • 只看金额大于500的高价值订单。

  • 只看某个店铺或某个类目的商品。

  • 只看已支付未发货的订单。

WHERE子句就是用来做条件筛选的。这一章我会带你彻底搞懂WHERE的各种用法:比较运算符、逻辑运算符、BETWEENINLIKE模糊查询、空值判断。学完之后,你能精准地从百万行数据中秒级提取你需要的行。

学习前准备:

  • 已完成MySQL安装(参考系列前几章)

  • 已安装DBeaver或Navicat

  • 准备一个练习数据库,比如where_demo

学习前环境准备

步骤1:确保MySQL服务已启动。

步骤2:创建练习数据库和表,并插入示例数据。

CREATEDATABASEwhere_demoCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;USEwhere_demo;-- 订单表CREATETABLEorders(order_idVARCHAR(50)PRIMARYKEY,user_idINTNOTNULL,shop_nameVARCHAR(50)NOTNULL,amountDECIMAL(10,2)NOTNULL,order_statusVARCHAR(20)NOTNULL,create_timeDATETIMENOTNULL,product_nameVARCHAR(100));INSERTINTOordersVALUES('ORD001',1001,'女装旗舰店',299.00,'已支付','2025-06-01 10:00:00','碎花连衣裙'),('ORD002',1002,'女装旗舰店',189.00,'已取消','2025-06-01 11:00:00','纯棉T恤'),('ORD003',1003,'男装专营店',599.00,'已支付','2025-06-02 09:30:00','牛仔裤'),('ORD004',1001,'女装旗舰店',399.00,'已支付','2025-06-03 14:20:00','雪纺衫'),('ORD005',1004,'童装店',99.00,'已完成','2025-06-03 16:00:00','儿童T恤'),('ORD006',1005,'女装旗舰店',1299.00,'已支付','2025-06-04 08:30:00','真丝连衣裙'),('ORD007',1002,'男装专营店',89.00,'已取消','2025-06-04 10:00:00','休闲短裤'),('ORD008',1006,'女装旗舰店',89.00,'已支付','2025-06-05 09:00:00',NULL),('ORD009',1007,'男装专营店',259.00,'已支付','2025-06-05 14:00:00','Polo衫');

WHERE条件筛选基础认知

WHERE子句用于过滤行,只保留满足条件的记录。它紧跟在FROM之后,在GROUP BY之前执行。

基本语法

SELECTFROMWHERE条件;

SQL执行顺序回顾

  1. FROM:确定数据来源

  2. WHERE:按行筛选

  3. GROUP BYHAVINGSELECTORDER BYLIMIT

在电商数据分析中的核心用途

  • 时间范围筛选(某天、某月、某季度)。

  • 数值区间筛选(金额大于500)。

  • 状态筛选(已支付、待发货)。

  • 文本匹配(店铺名称、商品名称)。

我的踩坑经历:我第一次写WHERE时,把条件写成了WHERE amount > 500 AND order_status = '已支付',结果正确。但后来我写了一个WHERE order_status = '已支付' AND amount > 500,效果一样。但切记:字符串值必须用单引号,数字不用。

比较运算符

4.1 基础语法

运算符含义
=等于
>大于
<小于
>=大于等于
<=小于等于
<>!=不等于

4.2 电商实操案例

案例一:查询金额大于500元的订单

SELECT*FROMordersWHEREamount>500;

预期结果:ORD003(599)、ORD006(1299)。

案例二:查询金额小于100元的订单

SELECT*FROMordersWHEREamount<100;

预期结果:ORD005(99)、ORD007(89)、ORD008(89)。

案例三:查询女装旗舰店的订单

SELECT*FROMordersWHEREshop_name='女装旗舰店';

预期结果:ORD001、ORD002、ORD004、ORD006、ORD008。

案例四:查询不是“已支付”的订单

SELECT*FROMordersWHEREorder_status<>'已支付';-- 或 WHERE order_status != '已支付';

预期结果:ORD002(已取消)、ORD005(已完成)、ORD007(已取消)。

4.3 分步操作

  1. 先确定要查询的表和列。

  2. 写出不带WHERE的查询,看全量数据。

  3. 加上WHERE和比较条件。

  4. 执行并验证结果行数。

避坑提醒=比较时,字符串要精确匹配(大小写和空格)。MySQL默认不区分大小写,但区分末尾空格。比如'女装旗舰店 '(多一个空格)匹配不到。

实操避坑提醒:金额比较时,确保amount列是数值类型,不能是带货币符号的字符串。否则比较结果可能错误。

逻辑运算符(AND、OR、NOT)

5.1 基础语法

  • AND:所有条件必须同时满足。

  • OR:至少满足一个条件。

  • NOT:取反。

5.2 电商实操案例

案例一:女装旗舰店且金额大于300元的订单

SELECT*FROMordersWHEREshop_name='女装旗舰店'ANDamount>300;

预期结果:ORD004(399)、ORD006(1299)。

案例二:女装旗舰店或男装专营店的订单

SELECT*FROMordersWHEREshop_name='女装旗舰店'ORshop_name='男装专营店';

预期结果:除童装店以外的所有订单(ORD001-004,006-009)。

案例三:金额大于500且状态为“已支付”,或者金额小于100且状态为“已支付”

SELECT*FROMordersWHERE(amount>500ORamount<100)ANDorder_status='已支付';

注意括号优先级:AND优先级高于OR,所以括号很重要。

预期结果:金额>500且已支付:ORD003(599)、ORD006(1299);金额<100且已支付:ORD008(89) → 共3条。

5.3 分步操作

  1. 先写单条件查询验证。

  2. AND/OR组合。

  3. 不确定优先级时加括号。

  4. 执行并验证。

避坑提醒

  • AND的优先级高于OR,所以条件1 OR 条件2 AND 条件3会被解释为条件1 OR (条件2 AND 条件3)。建议始终用括号明确逻辑。

我的踩坑经历:我写过WHERE shop_name = '女装旗舰店' OR shop_name = '男装专营店' AND amount > 500,结果只筛选出男装专营店中金额>500的,女装旗舰店全部返回了。因为AND优先级高,实际是shop_name = '女装旗舰店' OR (shop_name = '男装专营店' AND amount > 500)。加上括号(shop_name = '女装旗舰店' OR shop_name = '男装专营店') AND amount > 500才是我想要的。

BETWEEN区间筛选

6.1 基础语法

WHEREBETWEEN下界AND上界;

等价于列 >= 下界 AND 列 <= 上界,包含边界值。

6.2 电商实操案例

案例一:查询金额在100到300元之间的订单(包含边界)

SELECT*FROMordersWHEREamountBETWEEN100AND300;

预期结果:ORD001(299)、ORD002(189)、ORD004(399? 399不在100-300之间,所以不包括)、ORD009(259) → 实际ORD004=399不在,ORD009=259在。重新确认:ORD001(299)是,ORD002(189)是,ORD009(259)是。ORD004(399)不是。

案例二:查询2025年6月3日到6月4日的订单

SELECT*FROMordersWHEREcreate_timeBETWEEN'2025-06-03 00:00:00'AND'2025-06-04 23:59:59';

预期结果:ORD004(6月3日14:20)、ORD005(6月3日16:00)、ORD006(6月4日08:30)、ORD007(6月4日10:00)。

6.3 避坑提醒

  • BETWEEN包含边界值,如果不想包含,用><组合。

  • 日期区间建议用>= start AND < end + 1,避免漏掉当天的23:59:59之后的记录。例如WHERE create_time >= '2025-06-03' AND create_time < '2025-06-05'

实操避坑提醒BETWEEN对日期时间类型要小心,因为时间精度可能到秒。最好用>=<配合。

IN集合筛选

7.1 基础语法

WHEREIN(1,2,...);

等价于多个OR条件。

7.2 电商实操案例

案例一:查询女装旗舰店和男装专营店的订单

SELECT*FROMordersWHEREshop_nameIN('女装旗舰店','男装专营店');

案例二:查询订单状态为“已支付”或“已完成”的订单

SELECT*FROMordersWHEREorder_statusIN('已支付','已完成');

预期结果:除已取消外的所有订单。

案例三:查询商品名称为特定几个商品的订单

SELECT*FROMordersWHEREproduct_nameIN('碎花连衣裙','牛仔裤','雪纺衫');

7.3 分步操作

  1. 列出需要匹配的值。

  2. IN替换多个OR,提高可读性。

  3. 执行验证。

避坑提醒

  • IN列表中的值类型要与列类型一致。

  • 如果列表很长,考虑用子查询(后续会讲)。

LIKE模糊查询

8.1 基础语法

WHERELIKE'模式';
  • %:匹配任意个字符(包括0个)。

  • _:匹配单个字符。

8.2 电商实操案例

案例一:查询商品名称中包含“T恤”的订单

SELECT*FROMordersWHEREproduct_nameLIKE'%T恤%';

预期结果:ORD002(纯棉T恤)、ORD005(儿童T恤)。

案例二:查询商品名称以“雪纺”开头的订单

SELECT*FROMordersWHEREproduct_nameLIKE'雪纺%';

预期结果:ORD004(雪纺衫)。

案例三:查询商品名称中第二个字是“裙”的订单(第一个字任意)

SELECT*FROMordersWHEREproduct_nameLIKE'_裙%';

预期结果:ORD001(碎花连衣裙)、ORD006(真丝连衣裙)。

8.3 分步操作

  1. 确定要模糊匹配的模式。

  2. %代表任意长度,_代表单个字符。

  3. 注意转义字符(如\%匹配字面%)。

避坑提醒

  • LIKE默认不区分大小写(MySQL),但区分字符集。

  • %开头的模式无法使用索引,性能差。尽量避免在大量数据上用LIKE '%keyword%'

我的踩坑经历:我曾用LIKE '%连衣裙%'去匹配商品名称,结果把“连衣裙”和“雪纺连衣裙”都找到了,但查询跑了10秒。后来加了全文索引才改善。模糊查询前%会导致全表扫描,谨慎使用

IS NULL / IS NOT NULL空值筛选

9.1 基础语法

WHEREISNULL;WHEREISNOTNULL;

注意:不能写成= NULL,因为NULL代表“未知”,任何与NULL的比较结果都是NULL(假)。

9.2 电商实操案例

订单表中有product_name为NULL的行(ORD008)。

案例一:查询商品名称为空的订单

SELECT*FROMordersWHEREproduct_nameISNULL;

预期结果:ORD008。

案例二:查询商品名称不为空的订单

SELECT*FROMordersWHEREproduct_nameISNOTNULL;

预期结果:除ORD008外的所有订单。

9.3 分步操作

  1. 确认哪些字段允许NULL。

  2. IS NULLIS NOT NULL筛选。

  3. 注意:NULL不能用=判断。

避坑提醒

  • 在统计中,COUNT(column)会忽略NULL值,COUNT(*)不会。

  • 空字符串''不是NULL,需要用= ''判断。

综合实操案例:618大促高价值订单与异常数据排查

10.1 案例背景

某服饰类目店铺618大促后需要完成以下分析:

  1. 筛选出女装类目中金额≥500元的高价值订单。

  2. 筛选出6月1日至6月3日之间男装专营店的已支付订单。

  3. 找出商品名称中包含“连衣裙”且金额大于300元的订单。

  4. 找出订单状态为空(NULL)的异常订单(假设有)。

  5. 找出金额在100到200之间或金额大于1000的订单。

  6. 找出收货地址(本例没有,改用product_name)为NULL的异常数据。

10.2 分步操作

步骤1:高价值女装订单

SELECT*FROMordersWHEREshop_name='女装旗舰店'ANDamount>=500;

预期结果:ORD006(1299)。

步骤2:男装专营店在特定日期的已支付订单

SELECT*FROMordersWHEREshop_name='男装专营店'ANDorder_status='已支付'ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-03';

注意BETWEEN包含6月3日全天,而ORD003是6月2日,ORD009是6月5日,所以只有ORD003符合。

预期结果:ORD003(599)。

步骤3:商品名称包含“连衣裙”且金额>300

SELECT*FROMordersWHEREproduct_nameLIKE'%连衣裙%'ANDamount>300;

预期结果:ORD006(真丝连衣裙,1299)。ORD001(碎花连衣裙)金额299不大于300,不包含。

步骤4:异常订单(product_name为空)

SELECT*FROMordersWHEREproduct_nameISNULL;

预期结果:ORD008。

步骤5:金额100-200或大于1000

SELECT*FROMordersWHERE(amountBETWEEN100AND200)ORamount>1000;

预期结果:金额100-200:ORD002(189)、ORD007(89? 89不在100-200)、ORD008(89不在)、ORD009(259不在) — 实际上只有ORD002=189?ORD009=259大于200,不属于。金额>1000:ORD006(1299)。所以结果为ORD002和ORD006。

步骤6:整合所有筛选条件(可选)

SELECT*FROMordersWHERE(shop_name='女装旗舰店'ANDamount>=500)OR(shop_name='男装专营店'ANDorder_status='已支付'ANDcreate_timeBETWEEN'2025-06-01'AND'2025-06-03')OR(product_nameLIKE'%连衣裙%'ANDamount>300)ORproduct_nameISNULL;

10.3 结果验证

执行以上查询,核对行数和数据是否符合业务预期。

📌 电商数据合规提示:在筛选用户信息时,如果user_id能关联到个人,筛选结果中不要直接导出用户ID明细,除非必要。另外,对product_name的模糊查询不会暴露敏感信息,但如果是用户昵称、地址等,要谨慎使用LIKE并限制结果集大小。

本章踩坑清单与合规总结

11.1 新手常见踩坑

错误原因正确做法
WHERE 列 = NULL不理解NULL特性IS NULL
字符串值不加单引号语法错误加单引号
LIKE '%keyword'导致全表扫描无法使用索引尽量避免,或使用全文索引
AND/OR优先级混淆缺少括号用括号明确逻辑
BETWEEN包含边界误用不想要边界值>=<
日期区间漏掉当天最后时刻时间精度问题< '日期+1'

11.2 性能优化建议

  • 尽量在WHERE中使用索引列。

  • 避免在条件中对列做函数转换(如WHERE DATE(create_time) = '2025-06-01'),会导致索引失效。

  • EXPLAIN查看执行计划,确认是否走索引。

结语

WHERE子句是SQL查询的灵魂。掌握比较、逻辑、区间、集合、模糊、空值六类条件筛选,你就能从海量数据中精准提取分析所需的数据行。

有问题的评论区留言,我看到会回复。

http://www.jsqmd.com/news/648772/

相关文章:

  • BGE-Large-Zh与Vue.js前端集成:打造智能搜索界面
  • Alibaba DASD-4B Thinking 对话工具 MathType 公式编辑技巧与 LaTeX 转换助手
  • 5分钟搞定!造相-Z-Image文生图引擎RTX 4090本地部署保姆级教程
  • C#上位机跨平台avalonia随记
  • 万物识别-中文-通用领域:新手友好的图片识别入门指南
  • Qwen3-TTS VoiceDesign实战:3步生成多语言智能语音助手
  • 别再只盯着VLM了!用VLA(Vision-Language-Action)模型搞定自动驾驶的感知-决策-控制闭环
  • 3 《3D Gaussian Splatting: From Theory to Real-Time Implementation》第三级:压缩、轻量化与存储优化 (一)
  • Nunchaku-FLUX.1-dev多尺寸适配教程:512x512/768x512/512x768参数设置指南
  • Ostrakon-VL-8B与数据库联动:实现餐饮评论的情感与视觉分析
  • Pixel Mind Decoder 成本优化全攻略:云原生部署下的资源调度与自动伸缩
  • WAN2.2文生视频ComfyUI工作流定制:接入LLM生成Prompt+自动视频合成流水线
  • 第六章:信号完整性(SI)基础
  • Qwen3-ASR-1.7B多场景落地:从会议转写到教学评估全覆盖
  • 丹青幻境快速部署:3分钟启动Z-Image Atelier,支持中文画意描述直输
  • 香橙派5 Plus摄像头避坑指南:从MIPI OV13855到USB罗技,ROS2 Humble下完整配置流程
  • 【技术底稿 15】SpringBoot 异步文件上传实战:多线程池隔离 + 失败重试 + 实时状态推送
  • 掌握AMD Ryzen硬件调试:SMUDebugTool新手完全指南
  • c++如何解析二进制协议中的位域字段_位运算符与结构体映射【实战】
  • 关于小红书流量的一些思考分享
  • GLM-4v-9b效果对比:Claude 3 Opus中文手写体识别率62%,GLM-4v-9b达91%
  • 终极开源回放工具:ROFL-Player 7大核心特性深度解析与实战应用指南
  • 如何永久保存你的QQ空间记忆?GetQzonehistory为你提供完整备份方案
  • Qwen1.5-1.8B GPTQ与Node.js后端集成:构建实时AI聊天应用
  • Git-RSCLIP GPU显存碎片化治理:避免OOM的batch_size动态调整策略
  • 图图的嗨丝造相进阶技巧:如何用负面提示词优化生成效果
  • Fish Speech 1.5语音合成效果惊艳展示:自然度媲美真人播音员
  • 从CLIP到Qwen-VL,多模态大模型云端协同部署的4层解耦架构(附阿里/华为/腾讯内部对比矩阵)
  • 解锁 Python 动态编程魅力:鸭子类型、类型检查最佳实践与全栈实战指南
  • P2241 统计方形(数据加强版)