having的语法

mysql中having关键词是用来做筛选的,一般主要和group by 关键词来一起使用,将分组后的数据进行聚合并作为进一步查询的条件的时候需要使用having关键字来进行筛选,当然having也可以不和group by 一起使用,这个时候它的作用和where差不多,having对应的语法如下:


SELECT

select_list

FROM

table_name

WHERE

search_condition

GROUP BY

group_by_expression

HAVING

group_condition

ORDER BY

order_by_condition

LIMIT

n;

常用的关键字中,having的执行顺序在 FROMWHERESELECTGROUP BY 、之后,在 ORDER BYLIMIT 之前,具体顺序入下图所示:

null

having的用法

假如我们有一张数据库表如下所示


CREATE TABLE `t_income` (

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '唯一自增id',

`income_date` varchar(255) NOT NULL COMMENT '收入年月',

`amount` float NOT NULL COMMENT '收入金额',

`target_amount` float NOT NULL DEFAULT '0' COMMENT '目标收入',

`create_time` datetime NOT NULL COMMENT '创建时间',

PRIMARY KEY (`id`) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  • 单独使用having,作用类似where,主要用来过滤满足条件的数据

select * from t_income having amount > 10;
  • having与group by共同使用,可以将group by聚合的结果作为查询条件来进行筛选

select income_date, sum(amount) as total_amount from t_income group by income_date having total_amount > 1000 ;
  • having还可以与where共同使用来进行条件过滤

select income_date,amount, create_time from t_income where create_time <'2019-01-01' having amount > 1000;
  • 其实having也支持多个聚合结果作为条件进行过滤

select income_date, sum(amount) as total_amount, sum(target_amount) as total_target, create_time from t_income group by income_date having total_amount > 1000 and total_target >1000;

但是上面的sql你在执行的过程中可能会报异常,造成该问题的主要原因是由于Mysql 5.7版本之后,数据库默认打开的了only_full_group_by的开关,通过下面的sql就可以查看你的数据库是否打开了这个开关

`

select @@global.sql_mode;

`

如果你想要关闭该开关,只需要执行下面的sql即可,但是你要有足够的权限才可以:

`

set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

`

这样的修改生效以后,如果你重新启动数据库的话,only_full_group_by的开关又会被打开,想要一劳永逸的修改这个开关的的话,需要my.ini配置文件中修改,需要在 [mysqld] 和 [mysql] 下添加

`

SET sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE

`

having和where的区别

通过上面的讲解和上图关于常用关键词的执行顺序的展示,having和where的主要区别已经非常明显啦,它们最大的区别在于执行顺序,where 是先于 group by 做的过滤,而 having 是在 group by 之后才进行的过滤,所以它可以使用 group by 的聚合结果作为条件进行筛选,这也是 having 在日常开发中最主要的作用