欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mysql中having的用法

程序员文章站 2022-07-13 16:09:10
...

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 之前,具体顺序入下图所示:
mysql中having的用法

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