小编典典

为什么MySQL允许您按未选择的列分组

sql

我正在读一本有关SQL的书(《山姆在10分钟内自学SQL》),尽管书名很不错。但是关于分组依据的一章使我感到困惑

“对数据进行分组是一个简单的过程。选定的列(查询中SELECT关键字后的列列表)是可以在GROUP
BY子句中引用的列。如果在SELECT语句中找不到列,则不能考虑到这是合乎逻辑的,如果不显示数据,可以将数据分组到报表上吗?”

当我在MySQL中运行此语句时,为什么会起作用?

select EMP_ID, SALARY
from EMPLOYEE_PAY_TBL
group by BONUS;

阅读 191

收藏
2021-04-07

共1个答案

小编典典

因为这本书是错误的。

中的列group byselect根据ANSI标准的中的列只有一种关系。如果某列位于中select,没有聚合函数,则该列(或其所在的表达式)需要位于该group by语句中。MySQL实际上放松了这种情况。

这甚至很有用。例如,如果要从表中为每个组选择具有最高ID的行,则写查询的一种方法是:

select t.*
from table t
where t.id in (select max(id)
               from table t
               group by thegroup
              );

(注意:还有其他方式可以编写这样的查询,这只是一个示例。)

编辑:

您建议的查询:

select EMP_ID, SALARY
from EMPLOYEE_PAY_TBL
group by BONUS;

可以在MySQL中工作,但可能不能在任何其他数据库中工作(除非BONUS碰巧是表上命名不佳的主键,但这是另一回事)。会为的每个值产生一行BONUS。对于每一行,它会得到一个任意EMP_IDSALARY该组中的行。该文档实际上说“不确定”,但我认为随意更容易理解。

真正 应该了解的这种类型的查询就是根本不使用它。中的所有“裸露”列SELECT(即没有聚合函数)都应位于中GROUP BY。在大多数数据库中,这是必需的。请注意,这与书中所说的 相反 。这样做没有问题:

select EMP_ID
from EMPLOYEE_PAY_TBL
group by EMP_ID, BONUS;

除了您可能会为同一行返回多个行EMP_ID而无法在它们之间进行区分。

2021-04-07