我有一个表log
,其中包含一个名为DateTime
的{{1}}列和一个外键TimeOfLog
。
我想做的是获取每个Logger_ID
的最新条目。
Logger_ID
但是,这或多或少返回属于该SELECT l.TimeOfLog AS TimeOfLog, l.Logger_ID AS Logger_ID
FROM `log` `l`
GROUP BY l.Logger_ID
HAVING MAX(l.TimeOfLog)
的随机TimeOfLog
。如果我再跑
Logger_ID
我得到了预期的最新结果。但是,我很确定SELECT MAX(l.TimeOfLog) AS TimeOfLog, l.Logger_ID AS Logger_ID
FROM `log` `l`
GROUP BY l.Logger_ID
不是属于该Logger_ID
的那个。
为什么/我在这里误会什么?
答案 0 :(得分:3)
要获得最大的行数,请不要认为group by
;考虑过滤。这是一种方法:
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
。
答案 1 :(得分:1)
您误解了GROUP BY
和HAVING
的工作原理。
GROUP BY
将指定列中具有相同值的所有行分组为一组。如果您选择GROUP BY
中未提及的一列而不使用聚合函数,则将从分组的行中随机获得一个值。
如果使用像MAX()这样的聚合函数,则该函数将应用于所有分组的行,然后选择结果。
HAVING
是类似于WHERE
的过滤器,但是在分组之前应用WHERE
,而在分组之后应用HAVING
过滤器。
您可以在那里使用聚合函数。例如,正确使用hading
SELECT column,
FROM table
GROUP BY column
HAVING COUNT(*) > 1
此查询将仅选择存在多次的列的值。
在您的示例中,只要组中至少一行的c.TimeOfLog不为空,则MAX(c.TimeOfLog)始终为true,因此不会过滤任何内容。