mysql - 错误代码 : 1055. SELECT 列表的表达式 #1 不在 GROUP BY 子句中并且包含非聚合列

标签 mysql

尝试了解有关以下错误的更多信息:

“错误代码:1055。SELECT 列表的表达式#1 不在 GROUP BY 子句中,并且包含非聚合列“companydb.e.dno”,该列在功能上不依赖于 GROUP BY 子句中的列;这与 sql_mode= 不兼容only_full_group_by"

my data set

my resulting table after join => 使用,从员工、部门中选择 dno、dnumber、dname、fname、ssn,其中 dno=dnumber 按 dname 排序;

根据我的理解,我可以在 select 子句中使用这些列,这些列对于使用 group by 和having 子句过滤的集合来说是唯一的。所以,这是我的困惑。

以下查询(查找员 worker 数最少的部门)因上述错误而失败:

select **dno**
from employee e, department d 
where e.dno=d.dnumber 
group by **dname** having count(ssn) =
     (select min(mycount) 
      from (select count(ssn) as mycount 
            from employee
            group by dno
           ) mytable
     );

但是下面的查询(对于相同的要求)是成功的:

select **dname**
from employee e, department d 
where e.dno=d.dnumber 
group by **dno** having count(ssn) =
     (select min(mycount) 
      from (select count(ssn) as mycount 
            from employee
            group by dno
           ) mytable
     );

并且从数据集中可以了解到,在have之前形成的每个组内的dno和dname是唯一的。那么,我可以使用 group by dno 选择 dname,但不能使用 group by dname 选择 dno?

最佳答案

如果选择列表中的值明确,MySQL 必须查看实际数据之前做出决定。这是语法错误,而不是值错误。

根据documentation ,Mysql会

Reject queries for which the select list, HAVING condition, or ORDER BY list refer to nonaggregated columns that are neither named in the GROUP BY clause nor are functionally dependent on (uniquely determined by) GROUP BY columns.

“功能上依赖于按列分组”是一种奇特的说法:如果您知道分组列的值,那么您毫无疑问就知道选择列表中引用的值。这就是你所说的:你假设如果你知道 dname ,你知道dno毫无疑问。

但目前,您的数据模型中没有任何内容可以阻止您,例如给每个部门使用相同的名称。只要你能做到,MySQL 就必须为此做好准备(并且必须拒绝你的查询,因为它不检查数据)。要告诉 MySQL 你不会/不能这样做,你可以定义 dnameunique not null 。然后dnumber/dnodname“唯一确定” ,和select dno ... group by dname应该可以。

您的第二个查询,select dname ... group by dno (相当于 select dname ... group by dnumber ),有效,因为它是主键(因此行中的每个值在功能上都依赖于它):如果您知道 dnumber/dnodname 的值没有歧义。 .

如果您不想添加该约束(但 100% 确定它得到满足,包括 null ),您也可以替换 select dno ... group by dnameselect dno ... group by dno 。如果dname实际上正如您所假设的那样明确,这在逻辑上是等效的(因为每个 dname 有一个 dno 并且每个 dno 有一个 dname )。出于同样的原因,您可以简单地使用 group by dno, dname在这两种情况下。或者,您可以使用例如select max(dno) ... group by dname ,这对结果也没有影响,因为 max()一个独特的值就是那个值。

所有这些方法都用于通知 MySQL 在任何情况下都可以在查看实际数据之前找到明确的值。如果你的假设是正确的,它不会改变结果(尽管它可能会对执行计划产生影响)。如果它更改了结果集,则您的假设不正确。

关于mysql - 错误代码 : 1055. SELECT 列表的表达式 #1 不在 GROUP BY 子句中并且包含非聚合列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51856270/

相关文章:

php - 来自多个表的 MySQL SUM

Mysql 不返回插入行的正确 id

mysql - 有没有什么最好的方法将批量数据从Mysql传输到Mongodb?

java - 如何使用mysql查询返回计数?

MySQL SELECT 行按组递增

mysql - UniqueEntity 验证失败 - Symfony?

mysql - 包含 2 个或更多字符的 sql 名称

mysql - 如果还没有日期行,如何将最近的行从一个表连接到另一个表并包含所有行?

mysql - 组日期为月份

mysql - 为什么 innodb 的 SHOW TABLE STATUS 如此不可靠?