相关文章推荐
小胡子的李子  ·  compiler construction ...·  1 年前    · 
豪情万千的小刀  ·  Android ...·  1 年前    · 
卖萌的充电器  ·  c# 字符串转类名-掘金·  1 年前    · 

看下面一段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的部门和城市。