MySQL:使用SELECT和MAX的新手
我有一张像这样的名为MySQL:使用SELECT和MAX的新手,mysql,Mysql,我有一张像这样的名为child的表 +---------+-----+ | name | age | +---------+-----+ | Alfred | 5 | | Maria | 6 | +---------+-----+ 当我运行时,从'child'中选择'name'我得到两行。没问题。这是我所期望的 但是如果我运行从'child'中选择'name',MAX('age')我会得到: +---------+------------+ | name | MAX(
child
的表
+---------+-----+
| name | age |
+---------+-----+
| Alfred | 5 |
| Maria | 6 |
+---------+-----+
当我运行时,从'child'中选择'name'
我得到两行。没问题。这是我所期望的
但是如果我运行从'child'中选择'name',MAX('age')
我会得到:
+---------+------------+
| name | MAX(`age`) |
+---------+------------+
| Alfredo | 6 |
+---------+------------+
这个结果对我来说是多余的。。我像以前一样期望两行,为什么它只输出一行?既然玛丽亚已经6岁了,为什么要输出阿尔弗雷多?在哪里可以找到有关此行为的文档?使用SQL聚合函数时应附带GROUP by子句。这里有一个很好的起点:您应该只使用GROUPBY SQL语句对诸如Average、Max等函数进行SQL聚合。否则,您将得到像这样未定义的行为
在这里,如果你只写
max(age)
,一切看起来都很好,你得到6,但现在你也要求它打印姓名(没有条件,即要求它打印所有姓名,而max只打印一行),因此,它尝试做一些智能的事情,打印第一行就是它在您的情况下所做的。您需要使用分组方式来获得多行。否则,聚合函数MAX()
将应用于所有行。注意,阿尔弗雷多的年龄实际上是5岁。该名称是本例中的组
MySQL在这里有点特殊,因为它不遵循ANSI标准SQL。通常在group by
子句中未指定select
子句中的列或对其应用聚合函数时,会引发错误。MySQL允许这样做(这将在将来的版本中更改,顺便说一句),并显示该组中的随机行。所以不要这样做
要在示例中获得两行,必须执行以下操作
SELECT name, MAX(age) FROM your_table GROUP BY name;
每个名称都是一个“组”。如果你的桌子上还有一个25岁的阿尔弗雷多,那么结果就是阿尔弗雷多-25和玛丽亚-6
当您想要获取属于组最大值的行时,它会变得更复杂。下面是一些如何解决这个问题的例子
为了安全起见,您可以通过设置sql_模式来禁用此功能。询问您的管理员您是否无权这样做。MAX()
是一个可与分组依据一起使用的选项。当GROUP BY
子句丢失时,任何RDBMS
都将从所有选定行生成一个组,并返回一个行
当涉及分组时,SELECT
子句中出现的表达式将独立计算。name
和MAX(age)
之间没有关系MAX(age)
是由WHERE
子句(您案例中的所有行)过滤的行中age
列的最大值
标准的SQL
语言不允许SELECT
ing不依赖于groupby
列或在聚合函数中使用的列。
MySQL允许这样做。从版本5.7.5开始,它遵守标准,并错误地拒绝此类查询。使用配置仍然可以实现旧的行为
如文档中所述,对于选择既不依赖于GROUP BY
列也不用于聚合函数的列。这是未定义的行为
返回您的查询:
SELECT 'name', MAX('age') FROM 'child'
它没有包含所有行的。然后,由于MAX(age)
(这是一个聚合函数),MySQL创建了一个包含所有过滤行(所有行)的组,并计算SELECT
子句中的每个表达式
MAX(age)
非常清楚,它的计算结果是在组中行的age
列中找到的最大值。那就是6
,仅此而已。不保留对提取它的行的引用
选择名称
会受到上述未定义行为的影响。服务器将选择任何值,这一次,它似乎更倾向于从第一行选择值。在另一台服务器上可能会有所不同。在同一台服务器上添加、删除或更新该表上的行后,它可能会有所不同。这是无法预测的
为什么会有这种行为?
为什么服务器不从同一行获取值,而该行的值是MAX(age)
?有那么难做到吗?--这就是很多初学者在开始使用SQL
时的想法
简单的回答是:因为没有这样的行
假设SQL
应该从它选择的同一行MAX('age')
中选择name
让我们在查询中添加更多内容:
SELECT 'name', MAX('age'), MIN('age'), AVG('age'), COUNT(*) FROM 'child'
如果上述断言正确,SQL
应该从包含MAX(age)
(第2行)的同一行中获取name
。如果有两行包含该值怎么办
但是,同时它应该从包含MIN(age)
的同一行中获取name
(嗯,这是第1行)
或者,它应该从is findsAVG(age)
(即5.5
;哎呀,没有这样的行)的行中获取它
在列中包含COUNT(*)
的行怎么样。。。呃。。。它应该在哪个列中检查计数(*)
?顺便说一句,COUNT(*)
不是年龄或名字,它只是一个数字。将其与存储在表中的值进行比较没有任何意义。MySQL的行为具有误导性,他不值得downvotesthanks,现在我得到了两行,但最大年龄的引用在哪里?如何检索最大年龄?这就是我现在得到的:+----------------+-----------+-----------+-----------+-----------+-----姓名|马克斯(
年龄)+-----------+-----------+-----------++-----------++------阿尔弗雷多| 5 | |玛丽亚| 6 |+-----------+-----------+-+-+
对不起,我不明白你的要求