网易首页 > 网易号 > 正文 申请入驻

掌握SQL单表查询:深入解析WHERE、GROUP BY与HAVING的执行顺序

0
分享至



很多人刚学 SQL 的时候,最容易卡住的不是 SELECT,而是这几个关键字到底谁先写、谁先执行:

  • WHERE
  • GROUP BY
  • HAVING
  • ORDER BY

看起来只是几个子句,真写题的时候却经常一脸懵:

  • 到底先过滤还是先分组?
  • WHERE 和 HAVING 有什么区别?
  • 为什么有时候能用别名,有时候又报错?
  • 明明语句写对了,结果却不对?

这篇文章就用最常见的单表查询场景,把这几个知识点彻底讲透。看完之后,你不光能写 SQL,还能真正理解它“是怎么跑起来的”。

一、先搞清楚:SELECT 语句到底怎么写

单表查询里,最常见的完整结构如下:

SELECT 字段, 聚合函数(字段)FROM 表名WHERE 条件GROUP BY 分组字段HAVING 分组后的条件ORDER BY 排序字段 ASC|DESC;

它的书写顺序是固定的:

  1. SELECT
  2. FROM
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. ORDER BY

这个顺序不能乱。

比如下面这种就是错的:

SELECT job, MIN(sal)FROM empHAVING MIN(sal) < 2000GROUP BY job;

因为 HAVING 不能写在 GROUP BY 前面。

二、书写顺序和执行顺序,不是一回事

这是 SQL 初学者最容易忽略的一点。

虽然你写 SQL 的时候是从 SELECT 开始写,但数据库真正执行的时候,并不是先执行 SELECT。

SQL 的常见执行顺序

FROMWHEREGROUP BYSELECTHAVINGORDER BY

你可以这么理解:

1)FROM:先确定从哪张表取数据

先找到数据源。

2)WHERE:先对原始数据做第一次过滤

这是行级过滤,发生在分组之前。

3)GROUP BY:把过滤后的数据分组

按某个字段,或者多个字段进行聚合统计。

4)SELECT:选择要显示的列

这时候才真正决定最终显示哪些字段和计算结果。

5)HAVING:对分组后的结果再过滤一次

这是组级过滤

6)ORDER BY:最后排序

排序永远是最后一步。

三、WHERE 和 HAVING,到底差在哪?

这是面试和考试里都非常高频的点。

WHERE

  • 作用对象:原始记录
  • 执行时机:分组前
  • 适合场景:普通条件过滤

例如:

SELECT *FROM empWHERE sal > 2000;

表示先把工资大于 2000 的员工筛出来。

HAVING

  • 作用对象:分组后的结果
  • 执行时机:分组后
  • 适合场景:对聚合结果进行过滤

例如:

SELECT deptno, AVG(sal)FROM empGROUP BY deptnoHAVING AVG(sal) > 2000;

表示先按部门分组,再筛选平均工资大于 2000 的部门。

一句话记忆

WHERE 过滤行,HAVING 过滤组。

这句话非常重要,很多 SQL 题本质上就在考这个。

四、单表查询实战:4个经典练习一次吃透

下面直接上实战,用 emp 表来演示。假设表结构里有这些常见字段:

  • empno:员工编号
  • ename:员工姓名
  • job:职位
  • sal:工资
  • deptno:部门编号
练习1:列出工资最小值小于 2000 的职位题目拆解

这道题别急着写代码,先读懂意思:

  • “工资最小值”说明要用聚合函数 MIN(sal)
  • “职位”说明要按 job 分组
  • “最小值小于 2000”说明要对分组后的结果过滤,所以要用 HAVING
SQL 写法

SELECT job, MIN(sal) AS min_salFROM empGROUP BY jobHAVING MIN(sal) < 2000;
示例运行结果

JOB        MIN_SALCLERK      800SALESMAN   1600ANALYST    1000
结果含义:这些职位对应的最低工资低于 2000。
这题为什么不能用 WHERE?

因为 MIN(sal) 是分组后才算出来的结果,WHERE 阶段根本还没分组,自然也拿不到聚合结果。

错误示例:

SELECT job, MIN(sal)FROM empWHERE MIN(sal) < 2000GROUP BY job;

这类写法会直接报错。

练习2:列出平均工资大于 1200 的“部门+职位”组合题目拆解

这题的关键在于:不是按部门分组,也不是按职位分组,而是按部门和职位的组合分组。

也就是说,一个分组单位是:

  • 某部门
  • 某职位

所以这里要使用多字段分组

SQL 写法

SELECT deptno, job, AVG(sal) AS avg_salFROM empGROUP BY deptno, jobHAVING AVG(sal) > 1200ORDER BY deptno ASC;
示例运行结果

DEPTNO  JOB        AVG_SAL10      MANAGER    245010      PRESIDENT  500020      ANALYST    300020      MANAGER    297530      MANAGER    285030      SALESMAN   1400
这题最容易犯的错错误1:把部门编号写成员工编号

很多人手一快写成 empno,这就完全变味了。

正确字段应该是:

deptno

不是:

empno
错误2:分组字段不完整

错误示例:

SELECT deptno, job, AVG(sal)FROM empGROUP BY deptno;

如果你 SELECT 里出现了 job,但 GROUP BY 里没有 job,很多数据库会直接报错。

因为数据库不知道同一个部门里多个 job 应该显示哪一个。

练习3:统计人数小于 4 的部门平均工资题目拆解

这题有两个目标:

  1. 统计每个部门的人数
  2. 找出人数小于 4 的部门
  3. 再展示这些部门的平均工资

所以这里要按 deptno 分组,同时用:

  • COUNT(1) 统计人数
  • AVG(sal) 统计平均工资
  • HAVING COUNT(1) < 4 做分组过滤
SQL 写法

SELECT deptno,COUNT(1) AS emp_count,AVG(sal) AS avg_salFROM empGROUP BY deptnoHAVING COUNT(1) < 4;
示例运行结果

DEPTNO  EMP_COUNT  AVG_SAL10      3          2916.67
这题为什么很经典?

因为它把两个聚合函数放在了一起:

  • COUNT() 负责判断人数
  • AVG() 负责输出平均工资

很多人一开始会误以为只能用一个聚合函数,其实完全可以在同一个查询里同时使用多个聚合统计。

练习4:统计各部门最高工资,并排除最高工资低于 3000 的部门

这道题的原意其实可以有两种理解,得看你想保留哪一类部门。

版本1:筛出“最高工资小于3000”的部门

如果你想找的是“哪些部门的最高工资还不到 3000”,那就这么写:

SELECT deptno, MAX(sal) AS max_salFROM empGROUP BY deptnoHAVING MAX(sal) < 3000;
示例结果

DEPTNO  MAX_SAL30      2850

这表示:30 号部门的最高工资只有 2850,说明整体薪资偏低。

版本2:排除最高工资低于3000的部门

如果题目说的是“排除最高工资小于 3000 的部门”,那实际保留的应该是最高工资大于等于 3000的部门。

写法应该是:

SELECT deptno, MAX(sal) AS max_salFROM empGROUP BY deptnoHAVING MAX(sal) >= 3000;
示例结果

DEPTNO  MAX_SAL10      500020      3000
这道题提醒我们什么?

做 SQL 题时,真正难的经常不是语法,而是审题

一定要看清楚题目到底是:

  • 筛选满足条件的组
  • 还是排除不满足条件的组

差一个字,SQL 逻辑就反了。

五、为什么有时候别名能用,有时候不能用?

很多人会注意到一个现象:

在 HAVING 里,有时可以写别名

SELECT deptno, AVG(sal) AS avg_salFROM empGROUP BY deptnoHAVING avg_sal > 2000;

某些数据库支持这种写法,因为 HAVING 执行时机晚于 SELECT。

但为了兼容性更好,建议你直接写完整表达式:

HAVING AVG(sal) > 2000

这样更稳。

在 WHERE 里通常不能直接用别名

因为 WHERE 执行在前,SELECT 里的别名此时还没生成。

比如:

SELECT sal * 12 AS annual_salFROM empWHERE annual_sal > 20000;

这类写法通常不成立。

六、写聚合查询时,最实用的审题方法

以后碰到 SQL 聚合题,直接按这三步走,基本不容易错。

第一步:先确定按什么分组

题目里如果出现:

  • 每个部门
  • 每种职位
  • 每个部门和职位组合

这些词,通常就是在提示你 GROUP BY 应该写什么。

第二步:再确定统计什么

题目里如果出现:

  • 平均工资 → AVG(sal)
  • 最低工资 → MIN(sal)
  • 最高工资 → MAX(sal)
  • 人数 → COUNT(1) 或 COUNT(*)

这一步决定聚合函数。

第三步:最后判断条件写 WHERE 还是 HAVING

这是最关键的判断标准:

  • 如果条件是针对原始字段,比如 sal > 1000,用 WHERE
  • 如果条件是针对统计结果,比如 AVG(sal) > 2000,用 HAVING
七、一个完整示例:把几个知识点串起来

假设现在有个需求:

查询 20 号和 30 号部门中,平均工资大于 1500 的职位,并按平均工资降序排列。
SQL 写法

SELECT deptno, job, AVG(sal) AS avg_salFROM empWHERE deptno IN (20, 30)GROUP BY deptno, jobHAVING AVG(sal) > 1500ORDER BY avg_sal DESC;
执行逻辑拆解第1步:FROM emp

从 emp 表取数据。

第2步:WHERE deptno IN (20, 30)

先把 20 号和 30 号部门之外的数据过滤掉。

第3步:GROUP BY deptno, job

按“部门+职位”组合分组。

第4步:SELECT deptno, job, AVG(sal)

计算每组平均工资,并选择要显示的列。

第5步:HAVING AVG(sal) > 1500

只保留平均工资大于 1500 的组。

第6步:ORDER BY avg_sal DESC

按平均工资从高到低排序。

示例运行结果

DEPTNO  JOB        AVG_SAL20      ANALYST    300020      MANAGER    297530      MANAGER    2850
八、几个非常容易踩坑的地方,提前避开1. WHERE 和 HAVING 混用

这是最常见的错。

错误思路:

  • 还没分组就想过滤平均工资
  • 已经是原始字段条件却硬写到 HAVING
2. 子句顺序写乱

正确顺序永远是:

SELECTFROMWHEREGROUP BYHAVINGORDER BY

别自己“自由发挥”。

3. GROUP BY 后,SELECT 中非聚合字段要保持一致

如果 SELECT 里出现普通字段,它通常就必须出现在 GROUP BY 中。

4. 审题不认真,逻辑写反

比如:

  • “小于 3000 的部门”
  • “排除小于 3000 的部门”

这两个 SQL 完全不是一回事。

九、建议收藏的几个高频模板1)按单字段分组统计

SELECT job, AVG(sal)FROM empGROUP BY job;
2)按多字段分组统计

SELECT deptno, job, AVG(sal)FROM empGROUP BY deptno, job;
3)分组后过滤

SELECT deptno, COUNT(*)FROM empGROUP BY deptnoHAVING COUNT(*) < 4;
4)先过滤再分组

SELECT deptno, AVG(sal)FROM empWHERE sal > 1000GROUP BY deptno;
5)分组后排序

SELECT deptno, AVG(sal) AS avg_salFROM empGROUP BY deptnoORDER BY avg_sal DESC;
十、总结:真正把 SQL 聚合查询想明白

单表查询看起来只是几行 SQL,实际上考的是三件事:

1. 你有没有看懂题

先分组什么,再统计什么,最后过滤什么。

2. 你知不知道 WHERE 和 HAVING 的边界

一个管原始数据,一个管分组结果。

3. 你是否理解执行顺序

写在前面的,不一定先执行;写在后面的,也不一定最后参与逻辑判断。

如果把这三件事想透了,后面的多表查询、子查询、复杂统计都会顺很多。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
切尔诺贝利被遗忘的60万人:拿铲子对抗核辐射,没人告诉他们真相

切尔诺贝利被遗忘的60万人:拿铲子对抗核辐射,没人告诉他们真相

网易新闻出品
2026-04-26 08:51:02
两男子应聘浦发银行销售代表,通过3轮面试,做了497元体检,工资卡都办好了,银行却以学历不符为由拒绝入职

两男子应聘浦发银行销售代表,通过3轮面试,做了497元体检,工资卡都办好了,银行却以学历不符为由拒绝入职

大象新闻
2026-04-24 16:49:09
白宫记者晚宴现场突发枪击事件!网友:川普可能要破美总统记录了

白宫记者晚宴现场突发枪击事件!网友:川普可能要破美总统记录了

火山詩话
2026-04-26 10:09:16
故事:聂磊称霸青岛十几年,最后因惹上一个女人,踢到铁板就此灭亡

故事:聂磊称霸青岛十几年,最后因惹上一个女人,踢到铁板就此灭亡

红豆讲堂
2024-12-17 10:54:23
赵丽颖在上海某高档餐厅被偶遇,瘦是真的瘦,素颜依然很美

赵丽颖在上海某高档餐厅被偶遇,瘦是真的瘦,素颜依然很美

一盅情怀
2026-04-25 19:36:00
Shams:联盟已开始调查掘金和森林狼冲突,预计G5前公布结果

Shams:联盟已开始调查掘金和森林狼冲突,预计G5前公布结果

懂球帝
2026-04-27 02:37:02
不想访华了?美国联合10国,对中国发起一轮猛攻,中方反制不隔夜

不想访华了?美国联合10国,对中国发起一轮猛攻,中方反制不隔夜

军机Talk
2026-04-25 17:10:51
王石真的老了!突然现身大梅沙,他赤裸着上半身,贴着胰岛素针头

王石真的老了!突然现身大梅沙,他赤裸着上半身,贴着胰岛素针头

火山詩话
2026-04-26 06:11:32
丁俊晖:就算赵心童状态不好也能世锦赛卫冕,他比所有球员都厉害

丁俊晖:就算赵心童状态不好也能世锦赛卫冕,他比所有球员都厉害

杨华评论
2026-04-26 21:47:34
感动 丁俊晖出局后祝福赵心童:他比谁都强 看好他世锦赛破咒卫冕

感动 丁俊晖出局后祝福赵心童:他比谁都强 看好他世锦赛破咒卫冕

我爱英超
2026-04-26 22:38:31
重磅:曝欧尔班准备出逃!和寡头转移资金离开匈牙利

重磅:曝欧尔班准备出逃!和寡头转移资金离开匈牙利

项鹏飞
2026-04-26 22:31:02
被卖缅甸女大学生后续:园区同意放人,黑幕曝光,父亲觉得不对劲

被卖缅甸女大学生后续:园区同意放人,黑幕曝光,父亲觉得不对劲

云舟史策
2026-04-26 17:10:28
4.26日晚间,多家上市公司,突发重磅利好,明天要起飞了

4.26日晚间,多家上市公司,突发重磅利好,明天要起飞了

风风顺
2026-04-27 01:05:03
美日底牌耗尽,争相派官员访华,特朗普口风变了,罕见替中国说话

美日底牌耗尽,争相派官员访华,特朗普口风变了,罕见替中国说话

兵器海陆空视频
2026-04-26 20:15:28
切尔西晋级足总杯决赛!换帅如换刀,5连胜狂轰21球,连刷4纪录

切尔西晋级足总杯决赛!换帅如换刀,5连胜狂轰21球,连刷4纪录

奥拜尔
2026-04-27 00:02:57
外媒炸锅了!当着日本航母的面,055竟然发射鹰击-20?

外媒炸锅了!当着日本航母的面,055竟然发射鹰击-20?

凡知
2026-04-26 21:00:16
结束了!再见爱德华兹!NBA最惨季后赛球队

结束了!再见爱德华兹!NBA最惨季后赛球队

篮球实战宝典
2026-04-26 19:48:57
CBA官方:贺希宁首次当选常规赛MVP+入选一阵 成深圳队史首人

CBA官方:贺希宁首次当选常规赛MVP+入选一阵 成深圳队史首人

醉卧浮生
2026-04-26 20:25:45
血亏8亿!华晨宇直播崩溃大哭,云南拿地建乐园,临门一脚被强拆

血亏8亿!华晨宇直播崩溃大哭,云南拿地建乐园,临门一脚被强拆

奇怪的鲨鱼们
2026-04-26 16:32:25
岛内最新民调公布,支持两岸统一人数有惊人变化,赖清德要急

岛内最新民调公布,支持两岸统一人数有惊人变化,赖清德要急

阿天爱旅行
2026-04-26 03:08:20
2026-04-27 05:03:00
侃故事的阿庆
侃故事的阿庆
几分钟看完一部影视剧,诙谐幽默的娓娓道来
612文章数 8294关注度
往期回顾 全部

科技要闻

涨价浪潮下,DeepSeek推动AI“价格战”

头条要闻

特朗普内阁又一女部长落马:强迫男下属为其提供性服务

头条要闻

特朗普内阁又一女部长落马:强迫男下属为其提供性服务

体育要闻

森林狼3比1掘金:逆境中杀出了多孙穆?!

娱乐要闻

仅次《指环王》的美剧,有第二季

财经要闻

事关新就业群体,中办、国办发文

汽车要闻

预售19.38万元起 哈弗猛龙PLUS七座版亮相

态度原创

家居
数码
亲子
公开课
军事航空

家居要闻

自然肌理 温润美学

数码要闻

三星Tab S12系列进入固件测试阶段 或配10500mAh大电池

亲子要闻

爸爸买的餐椅太好了,早知道早买了#餐椅 #宝宝板凳 #宝宝吃饭 #宝妈推荐

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

伊朗总统:不会在压力、威胁下进行谈判

无障碍浏览 进入关怀版