我正在读一本关于SQL的书(Sams在10分钟内自学SQL),尽管它的标题很好。但是关于群组的章节让我感到困惑
“分组数据是一个简单的过程。所选列(列表列表如下) 查询中的SELECT关键字)是可以在GROUP中引用的列 BY子句。如果在SELECT语句中找不到列,则无法在其中使用 GROUP BY子句。如果你考虑一下,这是合乎逻辑的 - 如何在数据上对数据进行分组 报告是否未显示数据? “
为什么我在MySQL中运行这个语句有效呢?
select EMP_ID, SALARY
from EMPLOYEE_PAY_TBL
group by BONUS;
答案 0 :(得分:5)
你是对的,MySQL确实允许你创建含糊不清且具有任意结果的查询。 MySQL相信你知道你在做什么,所以你有责任避免这样的查询。
您可以让MySQL以更标准的方式强制执行GROUP BY:
mysql> SET SQL_MODE=ONLY_FULL_GROUP_BY;
mysql> select EMP_ID, SALARY
from EMPLOYEE_PAY_TBL
group by BONUS;
ERROR 1055 (42000): 'test.EMPLOYEE_PAY_TBL.EMP_ID' isn't in GROUP BY
答案 1 :(得分:4)
因为这本书错了。
根据ANSI标准,group by
中的列与select
中的列只有一个关系。如果列在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_ID
和SALARY
。文档实际上说“不确定”,但我认为任意更容易理解。
你应该真正知道这种类型的查询只是不使用它。 SELECT
中的所有“裸”列(即没有聚合函数)都应该在GROUP BY
中。大多数数据库都需要这样做。请注意,这是本书所说的逆。这样做没有问题:
select EMP_ID
from EMPLOYEE_PAY_TBL
group by EMP_ID, BONUS;
除了您可能会为同一EMP_ID
获取多行而无法区分它们。