文章目录

  • WHERE 与 HAVING
  • WHERE 与 ON

SQL 提供了多种对数据进行过滤的方式,包括WHEREHAVING以及ON子句等。虽然它们都能够实现类似的功能,但是你知道它们之间的区别吗?让我们一起来探讨一下。

除非特殊说明,以下内容适用于各种数据库,包括 MySQL、Oracle、SQL Server、PostgreSQL 以及 SQLite 等;其中的示例表和数据来源于 GitHub。

WHERE 与 HAVING

WHEREHAVING的根本区别在于:

  • WHERE子句在GROUP BY分组和聚合函数之前对数据行进行过滤;
  • HAVING子句对GROUP BY分组和聚合函数之后的数据行进行过滤。

因此,WHERE子句中不能使用聚合函数。例如,以下语句将会返回错误:

-- 查找人数大于 5 的部门
select dept_id, count(*)
from employee
where count(*) > 5
group by dept_id;

由于在执行WHERE子句时,还没有计算聚合函数 count(*),所以无法使用。正确的方法是使用HAVING对聚合之后的结果进行过滤:

-- 查找人数大于 5 的部门
select dept_id, count(*)
from employee
group by dept_id
having count(*) > 5;
dept_id|count(*)|
-------|--------|4|       9|5|       8|

另一方面,HAVING子句中不能使用除了分组字段和聚合函数之外的其他字段。例如,以下语句将会返回错误:

-- 统计每个部门月薪大于等于 30000 的员工人数
select dept_id, count(*)
from employee
group by dept_id
having salary >= 30000;

因为经过GROUP BY分组和聚合函数之后,不再存在 salary 字段,HAVING子句中只能使用分组字段或者聚合函数。

⚠️SQLite 虽然允许HAVING子句中出现其他字段,但是得到的结果不正确。

从性能的角度来说,HAVING子句中如果使用了分组字段作为过滤条件,应该替换成WHERE子句;因为WHERE可以在执行分组操作和计算聚合函数之前过滤掉不需要的数据,性能会更好。下面示例中的语句 1 应该替换成语句 2:

-- 语句 1
select dept_id, count(*)
from employee
group by dept_id
having dept_id = 1;-- 语句 2
select dept_id, count(*)
from employee
where dept_id = 1
group by dept_id;

当然,WHEREHAVING可以组合在一起使用。例如:

select dept_id, count(*)
from employee
where salary > 10000
group by dept_id
having count(*) > 1;
dept_id|count(*)|
-------|--------|1|       3|

该语句返回了月薪大于 10000 的员工人数大于 1 的部门;WHERE用于过滤月薪大于 10000 的员工;HAVING用于过滤员工数量大于 1 的部门。

WHERE 与 ON

当查询涉及多个表的关联时,我们既可以使用WHERE子句也可以使用ON子句指定连接条件和过滤条件。这两者之间的主要区别在于:

  • 对于内连接(inner join)查询,WHEREON中的过滤条件等效;
  • 对于外连接(outer join)查询,ON中的过滤条件在连接操作之前执行,WHERE中的过滤条件(逻辑上)在连接操作之后执行。

对于内连接查询而言,以下三个语句的结果相同:

-- 语句 1
select d.dept_name, e.emp_name, e.sex, e.salary
from employee e, department d
where e.dept_id = d.dept_id
and e.emp_id = 10;
dept_name|emp_name|sex|salary |
---------|--------|---|-------|
研发部   |廖化    |男  |6500.00|-- 语句 2
select d.dept_name, e.emp_name, e.sex, e.salary
from employee e
join department d on (e.dept_id = d.dept_id and e.emp_id = 10);
dept_name|emp_name|sex|salary |
---------|--------|---|-------|
研发部   |廖化    |男  |6500.00|-- 语句 3
select d.dept_name, e.emp_name, e.sex, e.salary
from employee e
join department d on (e.dept_id = d.dept_id)
where e.emp_id = 10;
dept_name|emp_name|sex|salary |
---------|--------|---|-------|
研发部   |廖化    |男  |6500.00|

语句 1 在WHERE中指定连接条件和过滤条件;语句 2 在ON中指定连接条件和过滤条件;语句 3 在ON中指定连接条件,在WHERE中指定其他过滤条件。上面语句不但结果相同,数据库的执行计划也相同。以 MySQL 为例,以上语句的执行计划如下:

id|select_type|table|partitions|type |possible_keys       |key    |key_len|ref  |rows|filtered|Extra|
--|-----------|-----|----------|-----|--------------------|-------|-------|-----|----|--------|-----|1|SIMPLE     |e    |          |const|PRIMARY,idx_emp_dept|PRIMARY|4      |const|   1|     100|     |1|SIMPLE     |d    |          |const|PRIMARY             |PRIMARY|4      |const|   1|     100|     |

SQL 面试题:WHERE 和 HAVING、ON 有什么区别?相关推荐

  1. 图解SQL面试题:经典50题

    图解SQL面试题:经典50题 已知有如下4张表: 学生表:student(学号,学生姓名,出生年月,性别) 成绩表:score(学号,课程号,成绩) 课程表:course(课程号,课程名称,教师号) ...

  2. sql计算留存_免费教程《图解SQL面试题》

    运营.产品经理.数据分析.软件开发等职位,SQL是必会的技能. 面试经常考察SQL,但是不会做,怎么办? 工作里遇到的业务问题,需要用SQL实现,怎么办? 为了帮助你解决这些问题,我写了一本免费教程& ...

  3. 基础SQL面试题(3)

    问题描述:为管理岗位业务培训信息,建立3个表:S (S#,SN,SD,SA) S#,SN,SD,SA 分别代表学号.学员姓名.所属单位.学员年龄C (C#,CN ) C#,CN 分别代表课程编号.课程 ...

  4. 基础SQL面试题(1)

    如下4个表: 1. Student(S#,Sname,Sage,Ssex) 学生表 2. Course(C#,Cname,T#) 课程表 3. SC(S#,C#,score) 成绩表 4. Teach ...

  5. sql 以a开头的所有记录_#9#猴子聊数据分析之常见的SQL笔试题和面试题(下)

    题目来源 猴子:常见的SQL笔试题和面试题(下)​zhuanlan.zhihu.com 1.SQL语言允许使用通配符进行字符串匹配的操作,其中'%'可以表示:多个字符 2.通过 SQL,如何从 &qu ...

  6. Sql面试题之三(难度:简单| 含答案)

    Sql面试题之三(难度:简单| 含答案) 答案: 1.SELECT B.name, B.Depart T.Content FROM B, T WHERE ( T.Content = '税法培训' an ...

  7. sql a 表 若包含b表 则a 表 列显示_几道常见的SQL面试题,看你能答对几道?

    分享几道比较常见的SQL面试题,在不看底部参考答案的情况下,看自己能做对几道. 1.用一条SQL 语句 查询出每门课都大于80 分的学生姓名 2. 学生表 如下: 删除除了自动编号不同, 其他都相同的 ...

  8. 30道经典SQL面试题讲解(11-20)

    本篇节选自书籍<对比Excel,轻松学习SQL数据分析>一书,主要讲解数据分析面试中常见的30道SQL面试题.1-10题见:30道经典SQL面试题讲解(1-10) 11 行列互换 现在我们 ...

  9. 30道经典SQL面试题讲解(1-10)

    本篇节选自书籍<对比Excel,轻松学习SQL数据分析>一书,主要讲解数据分析面试中常见的30道SQL面试题. 1 查询每个班学生数 现在有一张全校学生信息表stu_table,这张表存储 ...

  10. lamda表达式修改数据_图解sql面试题:如何按条件修改数据?

    ​[题目] 下图表名是"班级表",请将班级中所有的1班.2班交换,0班变为3班.要求只使用更新语句(update),不要使用select语句. [解题思路] 1. 题目要求按条件更 ...

最新文章

  1. Elasticsearch2.2.0配置文件说明
  2. 3D人脸重建——PRNet网络输出的理解
  3. smtplib 抄送邮件_用Python收发电子邮件
  4. MySQL数据库常用命令汇总
  5. Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题
  6. 零拷贝实现高效的数据传输 -Efficient data transfer through zero copy
  7. 量化投资与信用风险机器学习建模
  8. spark保存数据到hbase_Spark读取Hbase中的数据
  9. iOS13深色模式/暗黑模式导航栏不自动适配的解决方案
  10. c语言课后作业,C语言练习题
  11. si24r1程序_Si24R1_Si24R1数据手册_2.4G无线射频芯片Si24R1_一牛网
  12. echarts制作两个纵轴的折线图
  13. Mysql性能调优之max_allowed_packet
  14. 计算广告系统算法与架构综述
  15. 电子齿轮 电子凸轮
  16. C/C++编程刷题分享—常见的经典面试题一
  17. tipask二次开发总结_测试经验总结(“二次开发”)
  18. 安装nodejs时提示Leaving directory
  19. 读内存为什么比读取磁盘快?快多少?
  20. RoboMaster机甲大师裁判系统赛事引擎助手-RM Referee Aid

热门文章

  1. python二元多次函数拟合_对python实现二维函数高次拟合的示例详解
  2. 踔厉奋发,笃行不怠 润和软件 HiHope 2021 OpenHarmony大事记
  3. hangye5:2011医疗行业网络营销发展动态
  4. 腾讯云-如何选择购云资源聚划算
  5. Linux 环境基础开发工具的使用
  6. 聊城大学计算机应用基础,聊城大学试题计算机应用基础试题.doc
  7. 计算机基础知识之了解计算机,计算机基础知识(计算机基础知识你了解吗?)...
  8. 5分钟告诉你如何成为一名黑客?从萌新成为大佬,只需掌握这5点(思维、编程语言、网络安全、入侵实操、法律)
  9. MYSQL 倒库操作
  10. 十进制进制法_什么是十进制计数法