MYSQL,GROUP BY 子句;这与 sql_mode=only_full_group_by [重复] 不兼容

Posted

技术标签:

【中文标题】MYSQL,GROUP BY 子句;这与 sql_mode=only_full_group_by [重复] 不兼容【英文标题】:MYSQL, GROUP BY clause; this is incompatible with sql_mode=only_full_group_by [duplicate] 【发布时间】:2018-04-13 06:23:34 【问题描述】:

以下 CodeIgniter 查询给出了错误提示;

SELECT 列表的表达式 #22 不在 GROUP BY 子句中并且包含 非聚合列“hw3.1.hw_homework.id”在功能上不起作用 依赖于 GROUP BY 子句中的列;这与 sql_mode=only_full_group_by

SELECT *, `studentid`, COUNT(studentid),
`be_user_profiles`.`first_name`, `be_user_profiles`.`last_name`
FROM `be_user_profiles` 
JOIN `be_users` ON `be_users`.`id`=`be_user_profiles`.`user_id` 
JOIN `hw_homework` ON `be_user_profiles`.`user_id`=`hw_homework`.`studentid` 
WHERE `be_user_profiles`.`advisor` = '20' 
AND `hw_homework`.`date` < '2018-06-15 00:00:00' 
AND `hw_homework`.`date` > '2017-08-24 00:00:00'
AND `active` = 1 
GROUP BY `be_user_profiles`.`user_id` 
ORDER BY COUNT(studentid) DESC

文件名:modules/organization/models/Mhomework.php

行号:226

$this->db->select('*,studentid,COUNT(studentid),be_user_profiles.first_name,be_user_profiles.last_name');
$this->db->from('be_user_profiles');
$this->db->join('be_users','be_users.id=be_user_profiles.user_id');
$this->db->join('hw_homework','be_user_profiles.user_id=hw_homework.studentid');
$this->db->where('be_user_profiles.advisor',$id);
$this->db->where('hw_homework.date <',$to);
$this->db->where('hw_homework.date >',$from);
$this->db->where('active',1);
$this->db->group_by('be_user_profiles.user_id');
$this->db->order_by('COUNT(studentid)','DESC');
$query = $this->db->get();

我删除了studentid 或添加了 group_by studentid 等,但它们都不起作用。

我知道我可以设置全局 SQL 模式,但我认为这不是我的解决方案。

mysql> 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';

mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

我想修复代码而不是解决方法。

【问题讨论】:

首先阅读 group by 的工作原理,因为您没有正确使用。然后请使用此错误消息等在谷歌上搜索其他问题。这是一个常见问题解答。将来,当阅读手册和谷歌搜索没有帮助并且您提出问题时,请阅读并采取行动minimal reproducible example。 查看我的 cmets 以了解已接受答案的问题。 【参考方案1】:

在标准 SQL 中,很难在带有 GROUP BY 的查询中使用 SELECT *。为什么?标准 SQL 要求 SELECTEed 列也出现在 GROUP BY 子句中,但在功能上依赖于 GROUP BY 中提到的值的列除外。

要编写聚合查询,最简单的方法是在 SELECT 和 GROUP BY 中枚举您想要的列。 MySQL 的notorious nonstandard extension to GROUP BY 允许您请求GROUP BY 子句中未提及的列,并继续为这些列返回一些不可预测的值。

要修复这个“正确”而不是绕过它,您需要摆脱*。改变

 $this->db->select('*,studentid,COUNT(studentid),be_user_profiles.first_name,be_user_profiles.last_name');

$this->db->select('studentid,COUNT(studentid),be_user_profiles.first_name,be_user_profiles.last_name');

为了获得最佳效果,请更改

$this->db->group_by('be_user_profiles.user_id');

$this->db->group_by('studentid,be_user_profiles.user_id');

【讨论】:

"Cannot SELECT *" 是错误的,你歪曲了问题。 @philipxy 我相信 O. Jones 正确地说 remove the select * 并且建议的 group by 子句依赖于 be_user_profiles.first_name, be_user_profiles.last_name 在功能上依赖于 be_user_profiles.user_id (如果为真)是允许的(尽管不是所有数据库都实现了标准中相对较新的部分)。 @Used_By_Already 阅读他们写的内容。我再说一遍,“不能SELECT *”是错误的,答案歪曲了问题。正确的是,您可以选择按这些列分组或在功能上依赖于这些列的列,并且您可以将列用作聚合操作数。在this example中不能使用select *。如果他们说那个,那么他们对select * 的看法不会错,他们仍然会在“你必须枚举你想要的列”中产生误导(因为枚举不是问题)并且他们' d 仍然缺乏一般情况。他们不应该回答这个长期存在的常见问题。 @philipxy 很明显,我确实阅读了 O. Jones 所写的内容。看来我们只是在准确性上有所不同,因为我也认为 您不能在使用 GROUP BY 的查询中使用 SELECT *。当 sql_mode=only_full_group_by 时,您是否可以参考? @Used_By_Already 显然,当 & 仅当 * 只是“按这些列分组或在功能上依赖于这些列的列”。例如,如果 & 仅当您在 CK 的超集上分组时——例如 PK 或 UNIQUE NOT NULL——因为所有列在功能上都依赖于这样一组列。但是,您不应该声称“在标准 SQL 中,您不能在使用 GROUP BY 的查询中使用 SELECT *”,除非 可以证明它遵循规则——这是您不能做到的,因为它没有.此外,说它仍然不会给出规则,而只是它们的一个结果。 PS我说要阅读它们,而不是你没有。

以上是关于MYSQL,GROUP BY 子句;这与 sql_mode=only_full_group_by [重复] 不兼容的主要内容,如果未能解决你的问题,请参考以下文章

与 sql_mode=only_full_group_by 不兼容的 MySQL 查询

如何从表中选择带有 oracle sql 中的 group by 子句的嵌套 json 对象?

mysql升级到8后报错,only_full_group_by报错

SQL中只要用到聚合函数就一定要用到group by 吗?

SQL Server 数据库中带有 Group by 子句的 JPQL 不起作用

MySQL的SQL语句优化-group by语句的优化