3
select person
from person
inner join collectionmember
    on sourceobjectid=personid
group by sourceobjectid 
having count(sourceobjectid)>1;

据说如果我们使用 group by 子句,则 group by 列名必须在 select 列列表中,但是上面的查询在没有选择 sourceobjectid 的情况下有效。这个查询是如何工作的?

4

2 回答 2

3

结果不是遇到的第一行。MySQL 非常清楚所谓的“隐藏列”的使用。从文档中引用:

MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。这意味着前面的查询在 MySQL 中是合法的。您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 ORDER BY 子句的影响。结果集的排序发生在选择值之后,并且 ORDER BY 不会影响服务器选择每个组中的哪些值。

此扩展的目的是允许您在表的主键上分组的查询,而不必放入所有其他列。这种行为实际上与 ANSI 标准是一致的。

在其他情况下使用“隐藏列”是值得怀疑的。选择的值是任意的。MySQL 甚至不保证它们来自同一行(尽管在实践中确实如此)。

于 2013-08-27T12:19:33.237 回答
1

MySQL 数据库会出现这种行为。它允许将任何列放在 select 子句中。您的示例的结果将具有每个组的 first*。

*什么是第一排取决于很多事情。

于 2013-08-27T11:50:46.930 回答