尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
零基础学SQL 12:SQL 子查询 vs JOIN:什么时候用哪个?(附实战对比)
上一篇讲了 INNER JOIN / LEFT JOIN / RIGHT JOIN 的用法这篇来解决一个更实际的问题同一条查询需求既能用子查询写也能用 JOIN 写到底该用哪个一、先看一个真实场景假设你有一张员工表和一张订单表。需求查询接单总额超过 5000 元的员工姓名。两种写法都能跑出来但思路和适用场景完全不同。二、示例表准备本系列所有文章都用下面这 4 张统一的练习表建一次就能跟着全系列练。-- 本系列统一练习表复制即可建表随时练手CREATETABLE员工表(员工idINTPRIMARYKEY,姓名VARCHAR(20),部门VARCHAR(20),工资DECIMAL(10,2),邮箱VARCHAR(50),手机VARCHAR(20),入职日期DATE);CREATETABLE订单表(订单idINTPRIMARYKEY,员工idINT,订单金额DECIMAL(10,2),下单时间DATETIME,付款时间DATETIME,状态VARCHAR(20));CREATETABLE用户表(用户idINTPRIMARYKEY,姓名VARCHAR(20),手机VARCHAR(20),邮箱VARCHAR(50),地址VARCHAR(100));CREATETABLE任务表(任务idINTPRIMARYKEY,员工idINT,备注VARCHAR(100),状态VARCHAR(20));-- 本篇用到的示例数据INSERTINTO员工表VALUES(1,张三,技术部,9000,zx.com,13800000001,2019-03-12),(2,李四,技术部,7500,lx.com,13800000002,2020-07-01),(3,王五,销售部,8200,wx.com,13800000003,2018-11-23),(4,赵六,人事部,6000,z2x.com,13800000004,2021-05-09);INSERTINTO订单表VALUES(101,1,2000,2026-01-05,2026-01-06,已完成),(102,1,3500,2026-01-20,2026-01-21,已付款),(103,2,800,2026-01-08,2026-01-09,已付款),(104,2,1200,2026-02-01,2026-02-02,已付款),(105,3,6000,2026-01-15,2026-01-16,已完成),(106,3,1500,2026-02-10,2026-02-11,已付款);注意赵六在订单表里没有记录。后面我们会用这个例子说明 NOT EXISTS 怎么查没接单的员工。三、写法 A子查询思路先算每个员工的接单总额再把满足条件的员工id返回给外层查询。SELECT姓名FROM员工表WHERE员工idIN(SELECT员工idFROM订单表GROUPBY员工idHAVINGSUM(订单金额)5000);结果姓名张三王五关键点子查询把问题拆成两步内层聚合 → 外层过滤适合先算一个条件再用这个条件筛选主表的场景逻辑清晰读起来像人话四、写法 BJOIN思路把两张表关联起来直接按员工分组再用HAVING过滤。SELECTe.姓名FROM员工表 eINNERJOIN订单表 oONe.员工ido.员工idGROUPBYe.员工id,e.姓名HAVINGSUM(o.订单金额)5000;结果姓名张三王五关键点一张查询解决所有问题没有嵌套需要把员工表里的所有非聚合列e.姓名也放进GROUP BY适合最终结果需要同时展示两张表字段的场景五、子查询 vs JOIN怎么选场景推荐写法原因只需要主表的字段条件是聚合后的结果子查询逻辑清晰外层查询简单结果需要同时展示多个表的字段JOIN一次关联减少嵌套判断存在/不存在如查有订单/没订单的员工子查询 EXISTS / NOT EXISTS语义最明确大量数据下的性能优化多数情况 JOIN 更优现代数据库对 JOIN 优化更成熟需要多层嵌套条件子查询分层表达更清晰六、三种常见需求的最佳写法场景 1查询有订单的员工存在性判断推荐EXISTS 子查询SELECT姓名FROM员工表 eWHEREEXISTS(SELECT1FROM订单表 oWHEREo.员工ide.员工id);为什么不推荐INEXISTS找到第一条匹配就停止IN要把子查询全部跑完数据量大时EXISTS通常更快场景 2查询没有订单的员工推荐NOT EXISTS 子查询SELECT姓名FROM员工表 eWHERENOTEXISTS(SELECT1FROM订单表 oWHEREo.员工ide.员工id);结果赵六。也可以用 LEFT JOIN IS NULL参考上一篇两种方式都对看团队规范和个人习惯。场景 3查询每个员工最近一次接单时间推荐窗口函数 ROW_NUMBER()比子查询和 JOIN 都优雅SELECT员工id,订单id,下单时间FROM(SELECT员工id,订单id,下单时间,ROW_NUMBER()OVER(PARTITIONBY员工idORDERBY下单时间DESC)ASrnFROM订单表)tWHERErn1;这是一个预告下一篇会专门讲窗口函数。七、性能对比一个容易踩的坑很多人以为子查询一定比 JOIN 慢其实不完全对。MySQL 5.7 及以前相关子查询外层每一行都执行一次子查询确实可能很慢MySQL 8.0 和 PostgreSQL优化器会自动把部分子查询改写成 JOIN性能差距已经很小经验判断数据量小万级以下→ 随便写优先保证可读性数据量大百万级以上→ 用EXPLAIN看执行计划哪条用索引、哪条扫描少就用哪条-- 查看执行计划EXPLAINSELECT姓名FROM员工表WHERE员工idIN(...);八、总结速查表需求类型推荐写法示例条件是聚合结果只取主表字段子查询 IN / EXISTS接单总额 5000 的员工结果需要多表字段一起展示JOIN员工名 订单总金额存在/不存在判断EXISTS / NOT EXISTS有/没有订单的员工取每组第一名/最新一条窗口函数每个员工最近一笔订单大数据量且要求高并发看 EXPLAIN 结果索引 执行计划说了算九、课后练习用上面的员工表和订单表写出 SQL查询接单总额前 3 名的员工姓名和总额提示用 JOIN 聚合 ORDER BY LIMIT。查询至少接过两笔订单的员工提示用子查询 HAVING COUNT。查询订单平均金额超过 2000 元的员工所在部门提示用 JOIN HAVING AVG。把答案发在评论区下一篇讲窗口函数。下一篇预告《SQL 窗口函数实战ROW_NUMBER / RANK / LAG / LEAD 一次讲透》
RELATED

相关推荐

Windows下VS2019手动编译gRPC:从环境配置到项目集成的完整指南

Windows下VS2019手动编译gRPC:从环境配置到项目集成的完整指南

1. 项目概述:为什么要在Windows上手动编译gRPC?在C服务端开发领域,gRPC是一个绕不开的高性能、跨语言的RPC框架。很多朋友,尤其是刚从Linux/Mac环境转到Windows的开发者,可能会觉得在Windows下用Visual Studio 2019&am…

📅 2026/9/17 8:45:12
零基础学SQL 11:_SQL 多表关联查询入门:INNER JOIN、LEFT JOIN、RIGHT JOIN 用法详解(附实战示例)

零基础学SQL 11:_SQL 多表关联查询入门:INNER JOIN、LEFT JOIN、RIGHT JOIN 用法详解(附实战示例)

一、为什么必须学会多表关联查询?实际工作中,数据很少全部放在一张表里。以一个公司的订单系统为例:员工表:存员工姓名、部门、工资订单表:存哪个员工接了哪笔订单、金额多少、状态如果你想查询 "张三名下的各笔订…

📅 2026/9/11 0:35:50
IUPBCP 登录、账户与账单 Clean-room 协议包

IUPBCP 登录、账户与账单 Clean-room 协议包

IUPBCP 登录、账户与账单 Clean-room 协议包 本目录是一套 clean-room、厂商中立(vendor-neutral) 的开发契约,用于演示印度 UPI 与 Bharat Connect 风格的登录、账户、账单、充值和售后聚合。它不是 Paytm 私有协议,也不是 Paytm…

📅 2026/10/24 6:56:12
MORE NEWS

更多资讯

📰

从法规问答到流程校验:快消标签 AI 初审场景验证

快消食品新品上市,包装标签合规审查是一道绕不开的环节,也是极易拖慢项目进度的卡点。 产品名称措辞、配料表排版、营养成分标注、宣传用语风险、品类对应法规标准,每一项都需要逐条核对。 当企业新品不断上新、SKU 快速迭代、包装版本频繁更…

📰

数据库内核手记 05:B+ 树(下)——删除、迭代器与并发控制

上一篇中,我们从根到叶查找,再通过向上传播的分裂完成插入。现在继续回答三个问题: 删除后节点太空,怎么办?范围查询怎样跨越多个叶子?一个线程正在修改结构,另一个线程怎样安全经过这里&#…

📰

鸿蒙PC构建实战:hvigor modelVersion 降级 + schema 清理 + ArkTS 编译三连坑完整复盘

欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/ 欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper 摘要 这篇文章记录了我在鸿蒙 PC(HarmonyOS 5.1.1 / API 19)上从零搭建 HarmonyPCDemo 工程时…

📰

多相机GigE Vision:触发与图像网段怎么分?

多相机GigE Vision系统里,“触发信号和图像数据走同一网段还是分离”这个问题,容易让人一开始就往“网络冲突”上想。但GigE Vision协议本身已经把这两件事分得很清楚了:GVCP(控制协议)管配置和触发,走UDP …

📰

pi coding agent CLI 深度解析:Agent Loop、TUI 与 LLM API 实战

1. 从“pi”这个标题说起:一个极简命名背后的技术野心第一次看到“pi”这个项目标题,很多人会本能地联想到圆周率、树莓派,或者某个数学常数。但如果你最近在开发者社区里泡过,尤其是关注 LLM 应用和命令行工具的那批人&#xff0…

📰

python神经网络Keras实现GRU及其参数量

神经网络Keras实现GRU及其参数量更新时间是二零二二年五月七日十时三十四分二十七秒, 作者是。这篇文章主要是为广大的朋友们介绍了如何利用Keras框架来实现GRU神经网络, 并且还涉及到了其参数量相关的内容, 对于有需要的朋友们来说, 这个可以作为借鉴和参考的素材, 希望能够帮…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬