聚合函数如何影响与其一起查询的列?

时间:2016-02-02 16:39:36

标签: mysql sql database

我有两张桌子: -

Movies(movieID,movieTitle,Director)

Rating(ratingID,movieID,movieRating,ratingDate)

现在我编写以下语法来查询这些表 -

SELECT movieTitle,max(movieRating) FROM Movie M,Rating R WHERE R.movieID = M.movieID GROUPBY R.movieID;

我想问的是:

如果movieID形成的每个子组都有一个唯一的max(movieRating)值,我只会为每个movieTitle子行获取一行max(movieRating)movieID -组。我不应该获得许多重复的movieTitlemax(movieRating)行,因为表中存在movieTitle条目的次数是多少?

让我用一个例子说明我的怀疑 -

假设我的参赛作品如下(我只包括相关的参赛作品):

movieID  movieTitle movieRating
  1      Lost Stars    3
  1      Lost Stars    4
  1      Lost Stars    5

当我对这些值运行查询时,我得到了 Lost Stars 5
作为答案。那行只返回一次作为答案。

我不应该得到 -
Lost Stars 5
Lost Stars 5
Lost Stars 5
作为答案。
那不应该是我得到的值3次(每次表中存在Lost Stars条目)?

你能解释为什么它以这种方式运作吗?

我是SQL的新手,如果这是一个非常基本的疑问,我道歉。我真的很感激我能得到的任何帮助。

3 个答案:

答案 0 :(得分:1)

您按movieID进行分组,这意味着每个movieID只会获得一行,所有汇总汇总到这些组。如果这些行具有相同的movieTitle,但某些行具有不同的movieID值,那么您将看到多行,但这是MySQL中的一个怪癖。我相信大多数RDBMS会在尝试返回不在GROUP BY中且不属于聚合函数的列时给出错误。

答案 1 :(得分:1)

GROUP BY将分组记录并返回不同的值。在您的情况下,记录都共享相同的电影标题和ID。唯一不同的值是评级,您要求的是最大值,而不是与每条记录相关的实际评级。

将结果与以下结果进行比较:

SELECT R.movieTitle,M.movieRating,max(M.movieRating) 
 FROM Movie M,Rating R
 WHERE R.movieID = M.movieID 
 GROUP BY R.movieID, R.movieTitle, M.movieRating;

注意:您必须按照select子句中不是聚合的任何字段进行分组,因此如果您选择它,则必须按movieTitle进行分组。

该查询的结果将为您提供所有3条记录,因为它正在选择movieRating值,该值因所有记录而异。

答案 2 :(得分:0)

GROUP BY将每个子行组的行分为一组,这些值由分组列组成。这里是movieID。因此每组只有一个这样的子行值。 SELECT中的聚合通过使用组的所有行来计算一个值,因此每个组只有一个值。这里,MAX(movieRating)。如果DBMS支持它,那么您可以在DBMS可以推断的列集上对每个指定的演绎规则的分组列上的每个子行值进行单值调整。其中一条规则是列集是否为UNIQUE。

如果你想要返回三行,那么你也应该在movieTitle上进行分组。

在版本5.7.5之前,MySQL默认禁用ONLY_FULL_GROUP_BY选项,因此如果违反这些规则,它就不会出错。它将从这些列的每个组的行中返回一些值。因此,如果值是唯一的(已声明或未声明),则查询将返回相同的值,就像推断出唯一性一样。这里是movieTitle。

但是从5.7.5开始,扣除工作和ONLY_FULL_GROUP_BY默认启用。因此,如果可以推断出你的单一性,那么在SELECT中可以使用movieTitle,但是否则会出错。您应该在基表中声明您知道的任何UNIQUE以支持扣除。

来自MySQL 5.7 Reference Manual Section 12.20.3 MySQL Handling of GROUP BY

  

MySQL 5.7.5及更高版本实现了对功能依赖的检测。如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下是这样),MySQL拒绝查询,其中选择列表,HAVING条件或ORDER BY列表引用既未在GROUP BY子句中命名也未在功能上依赖于它们的非聚合列。 (在5.7.5之前,MySQL不检测功能依赖性,默认情况下不启用ONLY_FULL_GROUP_BY。有关5.7.5之前行为的描述,请参阅MySQL 5.6参考手册。)

  

参见第12.20.4节“功能依赖性的检测”。