Mysql 为什么让MAX()返回与SELECT MAX()不同的值?

Mysql 为什么让MAX()返回与SELECT MAX()不同的值?,mysql,sql,Mysql,Sql,我有一个表log,其中包含一个名为TimeOfLog的DateTime列和一个外键Logger\u ID SELECT l.TimeOfLog AS TimeOfLog, l.Logger_ID AS Logger_ID FROM `log` `l` GROUP BY l.Logger_ID HAVING MAX(l.TimeOfLog) 我想做的是根据Logger\u ID获取最新条目 SELECT l.TimeOfLog AS TimeOfLog, l.Logger_ID AS Log

我有一个表
log
,其中包含一个名为
TimeOfLog
DateTime
列和一个外键
Logger\u ID

SELECT l.TimeOfLog AS TimeOfLog, l.Logger_ID AS Logger_ID 
FROM `log` `l` 
GROUP BY l.Logger_ID
HAVING MAX(l.TimeOfLog)
我想做的是根据
Logger\u ID
获取最新条目

SELECT l.TimeOfLog AS TimeOfLog, l.Logger_ID AS Logger_ID 
FROM `log` `l` 
GROUP BY l.Logger_ID
HAVING MAX(l.TimeOfLog)
但是,这或多或少会返回属于该
记录器ID
的随机
TimeOfLog
。如果我跑了

SELECT MAX(l.TimeOfLog) AS TimeOfLog, l.Logger_ID AS Logger_ID 
FROM `log` `l` 
GROUP BY l.Logger_ID
我得到了预期的、最新的结果。但是,我非常确定
记录器ID
不是属于
TimeOfLog


为什么/我在这里误解了什么?

要获得最大的行数,不要认为
分组;想想过滤。这里有一种方法:

select l.*
from log l
where l.timeoflog = (select max(t2.timeoflog)
                     from log l2
                     where l2.logger_id = l.logger_id
                    );
如果您只需要最长的时间,那么聚合是合适的:

select logger_id, max(timeoflog)
from log l
group by logger_id;
你有这样的表达:

HAVING MAX(l.TimeOfLog)

这只是检查最大值是否不是
0
NULL

要获得最大行,不要认为
分组;想想过滤。这里有一种方法:

select l.*
from log l
where l.timeoflog = (select max(t2.timeoflog)
                     from log l2
                     where l2.logger_id = l.logger_id
                    );
如果您只需要最长的时间,那么聚合是合适的:

select logger_id, max(timeoflog)
from log l
group by logger_id;
你有这样的表达:

HAVING MAX(l.TimeOfLog)

这只是检查最大值是否不是
0
NULL

您误解了
分组和
拥有
的工作方式

分组依据
将指定列中具有相同值的所有行分组到一个组中。如果未使用agregate函数而选择了
GROUP BY
中未提及的一列,则将从分组行中随机获取一个值

如果使用类似MAX()的agregate函数,则该函数将应用于所有分组行,然后选择结果

HAVING
是一个类似于
WHERE
的过滤器,但在分组之前应用
WHERE
,而在分组之后应用
HAVING
过滤器。 您可以在那里使用聚合函数。例如,have的正确用法可能是

SELECT column, 
FROM table
GROUP BY column
HAVING COUNT(*) > 1
此查询将只选择多次出现的列的值


在您的示例中,只要组中至少有一行的c.TimeOfLog不为空,MAX(c.TimeOfLog)将始终为真,因此它不会过滤任何内容。

您误解了
分组依据和
拥有
的工作原理

分组依据
将指定列中具有相同值的所有行分组到一个组中。如果未使用agregate函数而选择了
GROUP BY
中未提及的一列,则将从分组行中随机获取一个值

如果使用类似MAX()的agregate函数,则该函数将应用于所有分组行,然后选择结果

HAVING
是一个类似于
WHERE
的过滤器,但在分组之前应用
WHERE
,而在分组之后应用
HAVING
过滤器。 您可以在那里使用聚合函数。例如,have的正确用法可能是

SELECT column, 
FROM table
GROUP BY column
HAVING COUNT(*) > 1
此查询将只选择多次出现的列的值


在您的示例中,只要组中至少有一行的c.TimeOfLog不为空,MAX(c.TimeOfLog)将始终为真,这样它就不会过滤任何内容。

在MySQL中打开strict_模式,您将看到第一次查询失败。如果您按某个对象分组-所有其他列都应聚合到select子句中,但这或多或少会返回属于该记录器ID的随机TimeOfLog,这是您选择group by子句中未包含的列时的预期行为。@forpas我知道它是,我只是补充了这一点作为澄清,因为这是一个更大的SQL查询的要求。为什么?它在逻辑上是错误的,如果只启用了“完整的”组,则在语法上也是错误的。
MAX(l.TimeOfLog)
在两个查询中都是正确的。在第一个查询中没有正确使用它
拥有MAX(l.TimeOfLog)
并不意味着它能做什么。它应该是
让MAX(l.TimeOfLog)=
在MySQL中打开strict_模式,您将看到第一次查询失败。如果您按某个对象分组-所有其他列都应聚合到select子句中,但这或多或少会返回属于该记录器ID的随机TimeOfLog,这是您选择group by子句中未包含的列时的预期行为。@forpas我知道它是,我只是补充了这一点作为澄清,因为这是一个更大的SQL查询的要求。为什么?它在逻辑上是错误的,如果只启用了“完整的”组,则在语法上也是错误的。
MAX(l.TimeOfLog)
在两个查询中都是正确的。在第一个查询中没有正确使用它
拥有MAX(l.TimeOfLog)
并不意味着它能做什么。应该是
让MAX(l.TimeOfLog)=
解决了这个问题,而没有指出我是个傻瓜,因为没有连接have需要一个布尔表达式,而MAX(l.TimeOfLog)返回一个DateTime。谢谢。这解决了问题,但没有指出我是个傻瓜,因为我没有连接需要一个布尔表达式,而MAX(l.TimeOfLog)返回一个DateTime。非常感谢。