03. Java 条件查询

1. 前言

在 MySQL 中使用 select 查询语句的时候,一般都会加上 where 语句或者 limit 语句限定查询结果的范围,两种子句都是过滤的作用。另外还有和 group by 语句配合使用的 having 限制条件。区分 where 和 having 语句的作用也是比较基础的题目。

2. where 和 having

面试官提问: 请阐述下在 MySQL 中 where 和 having 关键词有什么区别?

题目解析: 为了更加清楚地阐述两个关键用法的不同,我们还是从实际例子出发。

进入上一节创建的测试数据库:

复制代码
USE mybj_demo;

然后进入测试数据库,创建 user 表:

复制代码
USE `mybj_demo`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '数据库主键',
  `username` varchar(32) DEFAULT NULL COMMENT '用户名',
  `password` varchar(32) DEFAULT NULL COMMENT '密码',
  `gender` int(2) DEFAULT NULL COMMENT '1:男性,2:女性',
  `age` int(10) DEFAULT NULL COMMENT '年龄',
  PRIMARY KEY (id) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

然后再插入一些测试数据:

复制代码
insert into user (username,password,gender,age) values ('小明','123456',1,20); 
insert into user (username,password,gender,age) values ('小红','123457',2,22); 
insert into user (username,password,gender,age) values ('小王','123458',1,24); 
insert into user (username,password,gender,age) values ('小刘','123459',2,26); 

2.1 where 和 having 都能使用的场景

复制代码
select username,password,gender,age from user where age >= 20;
select username,password,gender,age from user having age >= 20;

上述两条 sql 都能执行成功,如果 select 之后的字段包含 having 修饰的字段,这种情况下 where 和 having 是等效的。

2.2 只能用 where,不能用 having 的场景

复制代码
select username,password,gender from user where age >= 20;
select username,password,gender from user having age >= 20;

第一条 sql 执行成功,执行第二条 sql 会报错:ERROR 1054 (42S22): Unknown column 'age' in 'having clause',翻译过来就是 "对于 having 语句,age 字段是未知的"。

having 执行的前置条件是:select xxx,... 筛选出的字段包含 having 修饰的关键词。

两者的执行顺序不同:因为 having 是从前面筛选出来的字段中再进行二次筛选,where 则是针对全表先进行筛选。

2.3 只能用 having,不能用 where 的场景

复制代码
select count(*),gender,avg(age) as avg_age from user group by gender where avg_age > 20;
select count(*),gender,avg(age) as avg_age from user group by gender having avg_age > 20;

我们的目的是 "按照性别进行分组,统计平均年龄大于 20 的人数、性别和平均年龄"。

但是第一条 sql 执行会报错:ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where avg_age > 20' at line 1,即对于 where 语句,全表并没有 avg_age 平均年龄这个字段,所以会搜索失败。

从上述的实验结果总结来看,where 和 having 的核心区别有三点:

① 使用范围的不同:

  • where:能够用于 select、update、delete 语句;
  • having:只能用于 select 查询语句。

② 执行顺序不同:

  • where 修饰的搜索条件是在分组完成之前执行;
  • having 修饰的搜索条件是在分组完成之后执行。如果一条 sql 语句同时包含 where 和 having 关键词,会先执行 where 搜索,再执行 having 搜索条件。

③ 聚合函数的联合使用:

  • where:不能联合聚合函数(sum、avg、count、max、min 这类)使用;
  • having:能够联合聚合函数使用。

3. 小结

本章节介绍了 where 和 having 语句的用法和不同点,候选人在阐述的时候需要抓住最核心的一点,where 语句在聚合之前筛选数据,having 语句在聚合之后对数据进行筛选,作用在 group by 语句之后。

相关推荐
血小板要健康9 分钟前
如何计算时间复杂度(上)
java·数据结构·算法
计算机学姐12 分钟前
基于SpringBoot的美食分享交流平台
java·spring boot·后端·spring·java-ee·intellij-idea·美食
henujolly12 分钟前
ethers.js读取合约信息
开发语言·javascript·区块链
Eugene__Chen15 分钟前
Java关键字(曼波版)
java·开发语言
lixin55655633 分钟前
基于深度生成对抗网络的高质量图像生成模型研究与实现
java·人工智能·pytorch·python·深度学习·语言模型
无望__wsk42 分钟前
Python第一次作业
开发语言·python·算法
Word码1 小时前
[C++语法]-vector(用法详解及实现)
开发语言·c++
代码雕刻家1 小时前
4.3.多线程&JUC-多线程的实现方式
java·开发语言
梦6501 小时前
网络传输七层协议
开发语言·网络·php
Knight_AL1 小时前
Spring Boot 事件机制详解:原理 + Demo
java·数据库·spring boot