mysql中不用group by 而直接使用having的疑问 ?

首先我了解的是在mysql中可以直接使用having,和where有一些区别,下面是我的疑问: 在mysql 8.0.26版本中 我想在一个表中获取年…
关注者
5
被浏览
10,458

3 个回答

#1 ONLY_FULL_GROUP_BY 是Mysql里sql_mode(可理解为SQL规范)的一类,即编写对数据进行分组聚合时需要显式的写上GROUP BY。

查看当前sql_mode

详细的介绍见之前总结的博文:

#2 是否可以省略GROUP BY? 可以。设置sql_mode为:

set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
mysql> SELECT age,name FROM stu HAVING age=MAX(age) OR age=MIN(age);
+------+--------+
| age  | name   |
+------+--------+
|    5 | 张三   |
+------+--------+
1 row in set (0.00 sec)

显然结果不是想要的,这涉及到第3点。

#3 关于HAVING语句,它的一般形式是:

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value

即聚合函数在比较符的左边,如:HAVING COUNT(id)>1、HAVING MAX(id)>300等。

#4 为啥HAVING在 ONLY_FULL_GROUP_BY模式下可以不跟聚合函数?见下例:

-- 1 HAVING后不跟聚合函数
SELECT name,age FROM stu 
HAVING age=5 OR age=75;

上述这条语句其实Mysql做了自动转换,即等价于下列语句(当然这里的MAX可以换成MIN、SUM或者混用)

-- 2 Mysql做了隐式转换,转成下式
SELECT name,age FROM stu
GROUP BY age,name
HAVING MAX(age)=5 OR SUM(age)=75;


关于第#4点的注释

1 当分组语句里只有HAVING,前面没GROUP BY时,则所有数据行视为一个分组。

WITH CTE AS(
SELECT '张三' name, 5 age UNION 
SELECT '李四' name, 75 age UNION 
SELECT '王五' name, 23 age UNION 
SELECT '赵六' name, 31 age UNION 
SELECT '秦七' name, 51 age UNION 
SELECT '张三2' name, 5) 
-- 注意:这里的HAVING"弱化"为WHERE
SELECT name,age FROM CTE 
HAVING age=5 OR age=75;
-- 注意:这里的GROUP BY  age,name得到的也是所有数据化。
SELECT name,age FROM CTE
GROUP BY age,name
HAVING MAX(age)=5 OR SUM(age)=75;

2 官网解释截图

#5 先聚合函数(min、max)再关联到原表得name和age字段:

WITH stu2 AS
SELECT '张三' name,5 age UNION 
SELECT '李四' name,75 age UNION 
SELECT '王五' name,23 age UNION 
SELECT '赵六' name,31 age UNION 
SELECT '秦七' name,51 age  
SELECT name,age FROM