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 之前,具体顺序入下图所示:
在这里插入图片描述

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与group by共同使用, 可以将group by聚合的结果作为查询条件来进行筛选
select income_date, sum(amount) as total_amount from t_income group by income_date having total_amount > 1000 and total_amount < 10000;


  • 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 在日常开发中最主要的作用

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐