SQL语句: where 和 having 的区别

分组查询时,select的字段(不包含聚合函数的字段)是否一定要都在group by的字段中?

例如:

select name,age,sum(money) from user group by 

上面所说情况在Mysql5.7之后:sql_mode=only_full_group_by 情况下适用,可以通过 select @@sql_mode;查询自己的sql_mode

解决方案:

  1. 修改sql_mode,删除:SET @@sql_mode = sys.list_drop(@@sql_mode, 'ONLY_FULL_GROUP_BY');(不推荐)
  2. group by 主键字段
  3. group by 唯一非空字段
  4. select 字段集合 from table group by 相同字段集合
select @@sql_mode;

SET @@sql_mode = sys.list_add(@@sql_mode, 'ONLY_FULL_GROUP_BY');

SET @@sql_mode = sys.list_drop(@@sql_mode, 'ONLY_FULL_GROUP_BY');

为什么在Mysql5.7版本后开启了:ONLY_FULL_GROUP_BY ?

主要是为了避免查询selelct语句当中出现语义不明确的列,对于一些比较严谨的语义来说它的作用相当重要,这是一个规范。

简单的说一旦设置ONLY_FULL_GROUP_BY启用,那么使用group by 语句时,你的输出语句当中只能是使用了聚合函数的字段和group by的字段,若有其他不明确的字段则报错。

group by having 与 where 的区别?

​ 这里我们必须明确sql语句的执行过程:

from --> where --> group by --> having -- > order by --> select;

​ 可以看到where是在分组前进行的条件筛选

​ having 是对分组后的数据进行条件筛选,保存符合条件的组数据,下面举个栗子:

# 创建学生信息表
CREATE TABLE `student1`
(
    `id`    int(11)     NOT NULL COMMENT '学号',
    `name`  varchar(60) NOT NULL COMMENT '姓名',
    `birth` date        NOT NULL COMMENT '出生日期',
    `sex`   varchar(3) DEFAULT NULL,
    `age`   int(11)     NOT NULL,
    `score` int(11)     NOT NULL,
    PRIMARY KEY (`id`)
);
# 插入数据
insert into student1
values (1, 'Tom', '1998-10-01', '男', 23, 96),
       (2, 'Jim', '1997-07-04', '男', 24, 95),
       (3, 'Lily', '1999-11-12', '女', 21, 99),
       (4, 'Lilei', '1996-09-21', '男', 25, 90),
       (5, 'Lucy', '1999-12-02', '女', 21, 93),
       (6, 'Jack', '1988-04-27', '男', 32, 89),
       (7, 'Liam', '1991-09-08', '男', 28, 100);
       
# 查询数据
## 1. 看男女各自的最高分
select sex, max(score) as maxScore
from student1
group by sex;

## 2. 查看男女最高分中大于99的组数据(需要先分组,再从分组后的数据中挑选合适的)
select sex, max(score) as maxScore
from student1
group by sex
having maxScore > 99

## 3. 在年龄小于25岁的学生里,看男女最高分中大于88的组数据 (先按照where条件筛选,然后进行分组,分组后再按照having筛选)
select sex, max(score) as maxScore
from student1
where age < 25
group by sex
having maxScore > 80