看下面一段SQL语句及运行结果:
从这个结果我们可以发现两件事情。第一,这条查询语句中没有group by子句,select子句中的非聚合字段没有出现在group by子句中,这与我们一贯的认知不同。类似语法的SQL查询语句在hive中是报错的(在MySQL也有可能报错,后面会详细说)。第二,这从这条语句的执行结果可以看出,SQL查询语句中的聚合函数字段执行完成,而非聚合字段似乎返回了满足where条件的第一条记录的order_id的值。但该order_id对应的(original_value-discount)的值并不是我们所求的max结果。
下面来分析一为什么会出现这中情况及结果。
通常MySQL5.7及以上版本中sql_mode是默认设置了
ONLY_FULL_GROUP_BY
模式的。一旦设置了该模式,会将两类SQL查询语句判定为不合法,具体如下:
-
第1类,select子句、having子句、order by子句中的非聚合函数字段没有group by子句的查询语句。
-
第2类,select子句、having子句、order by子句中的非聚合函数字段与group by 子句中字段没有函数依赖(functional dependency)。
再来看上面那段SQL语句,没有group by子句,也就意味着select 子句中的非聚合函数字段order_id没有出现在group by子句中,也就不存在函数依赖关系。所以我们可以推测我的MySQL的sql_mode中没有设置ONLY_FULL_GROUP_BY模式。但是在MySQL 5.7及以上版本中,ONLY_FULL_GROUP_BY模式是默认开启的,而关掉该模式可以在my.ini文件中修改sql_mode参数。具体如下:
MySQL8.0中的若是没有my.ini文件,可以参考
https://www.cnblogs.com/RayWang/p/9347874.html
。
接着在看在关闭了ONLY_FULL_GROUP_BY模式下,会如何处理在其开启状态下判定为不合法的两类SQL查询语句。
-
首先,非聚合字段没有出现在group by 子句中。
如果select子句中有未出现在group by子句中的普通字段,这是服务器或从每个组中随机选择一个值输出。
此时,上述SQL查询语句等价于如下代码:
-
其次,非聚合字与group by中的字段不存在函数依赖关系。
先来看看什么是函数依赖。MySQL函数依赖是指:X能够决定Y,即当X确定之后,Y也就确定了,则我们说Y函数依赖X。 以下面代码为例:
从对原始数据的分析中可以发现,order_id其实是表的主键,那自然当按order_id进行分组之后,就已经在每个分组内部完成了cust_id的分组。所以上述代是可以运行的。但是字段之间的函数依赖只能基于键,基于相等性及基于视图建立。其他情况,及时X唯一确定了一个Y,也不能算是函数依赖。如下:
在上述SQL代码中,一个city,只会对一个area,但仍然提示1055错误。
参考资料:
1.
https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
2.
https://dev.mysql.com/doc/refman/5.7/en/group-by-functional-dependence.html
首先从一个无意中运行的例子讲起。数据表结构及数据如下(建表语句及插入语句就不提供了)。看下面一段SQL语句及运行结果:从这个结果我们可以发现两件事情。第一,这条查询语句中没有group by子句,select子句中的非聚合字段没有出现在groupby子句中,这与我们一贯的认知不同。类似语法的SQL查询语句在hive中是报错的(在MySQL也有可能报错,后面会详细说)。第二,这从...
执行
GROUP
BY
子句
的最一般的方法:先扫描整个表,然后创建一个新的临
时
表,表
中
每个组的所有行应为连续的,最后使用该临
时
表来找到组并应用
聚集
函数
(如果有
聚集
函数
)。在某些情况
中
,
MySQL
通过访问索引就可以得到结果,而
不用
创建临
时
表。此类查询的 EXPLAIN 输出显示 Extra列的值为 Using index for
group
-by。
一。 松散索引扫描
1.满足条件
查询针对一个表。
GROUP
BY 使用索引的最左前缀。
只可以使用MIN()和MAX()
聚集
函数
,并且它们均指向相同的列。
表t1(c1,c2,c3,c4) 有一个索引 idx(c1,c2,c3):
SQL
中
只要用到
聚合函数
就一定要用到
group
by 吗?今天记录一个弱智问题,一直没发现这个问题。答:看情况1、当
聚集
函数
和非
聚集
函数
出现在一起
时
,需要将非
聚集
函数
进行
group
by
2、当只做
聚集
函数
查询
时
候,就不需要进行分组了。举例来说,
SELECT SUM(TABLE.A ) FROM TABLE上述SQL不需要使用
Group
by 进行分组,因为其
中
没有
非聚合字段,所以
不用
Group
by 也可以。如果是SELECT SUM(TABLE.A ),MAX(B), FROM TABLE
GROUP
- 没见过
group
by没和
聚合函数
一起使用的
- 不会报错,新版
mysql
默认配置可以这样,如果要像老版之前。可以修改下配置。但是这样查出来的数据
没有
准确性。因为查询的未分组的列结果是随机的,仔细看解释
- 对,默认隐含分组了,结果看到不对
- 看我发的图,默认给合并了,你做个试验,看结果数据对不...
首先引入语句来源,表结构和数据如下:
需求是:查出员工(personname)在不同店铺(store)的总薪酬(salary),相同店铺输出store,不同店铺输出multi_store。
正确查询语句如下:
SELECT personname,(case when count(distinct Store)>1 then 'multi_store' else MAX ( s...
在
MySQL
中
,
GROUP
BY
子句
用于将结果集按照一个或多个列进行分组,并对每个组计算
聚合函数
的值,如SUM、COUNT、AVG等。
GROUP
BY
子句
的基本语法如下:
SELECT column1, column2, ...
FROM table_name
WHERE condition
GROUP
BY column1, column2, ...;
其
中
,column1, column2等表示要分组的列名。注意,SELECT语句
中
的每个列名必须是
GROUP
BY
子句
中
列名的子集或
聚合函数
的参数,否则
MySQL
会报错。
例如,下面的查询语句将按照city列分组,并计算每个城市的平均工资:
SELECT city, AVG(salary)
FROM employee
GROUP
BY city;
如果需要按照多个列进行分组,可以在
GROUP
BY
子句
中
指定多个列名,用逗号分隔,例如:
SELECT department, city, AVG(salary)
FROM employee
GROUP
BY department, city;
需要注意的是,如果SELECT语句
中
包含
聚合函数
,那么查询结果
中
的列名将是
聚合函数
的别名,而不是原始表
中
的列名。如果需要指定别名,可以使用AS关键字,例如:
SELECT department, city, AVG(salary) AS average_salary
FROM employee
GROUP
BY department, city;
最后,如果需要过滤分组后的结果集,可以在
GROUP
BY
子句
之后使用HAVING
子句
,例如:
SELECT department, city, AVG(salary) AS average_salary
FROM employee
GROUP
BY department, city
HAVING AVG(salary) > 5000;
这个查询将只返回平均工资大于5000的部门和城市。