数据:( log_time是DATETIME
类型)
log_id | action | log_time | user
--------------------------------------------------
1 Processed 2011-02-28 16:38:48 1
2 Processed 2011-03-02 16:56:43 5
3 Processed 2011-03-02 17:00:17 5
4 Processed 2011-03-03 08:59:33 5
查询:
SELECT log_time, user
FROM logs
WHERE action = "Processed"
GROUP BY action
HAVING MAX(log_time)
结果:
log_time | user
--------------------------
2011-02-28 16:38:48 1
显然,这根本没有最大log_time。如果我将查询更改为...
SELECT MAX(log_time), user
FROM logs
WHERE action = "Processed"
然后我自然而然地得到了:
log_time | user
--------------------------
2011-03-03 08:59:33 1
现在,我显然想要的数据是第4行:3月3日的数据,但是用户5.我知道我可以通过做一个简单的SELECT ... ORDER BY log_time DESC LIMIT 1
来获得这个数据。但我的问题是,我对这些不正确的MAX()
查询做了什么?在我看来,如果我使用HAVING MAX()
运行查询,它会给我一行,好吧,有最大值。我不明白MAX()
的工作原理是什么?
编辑:详细说明我的问题,基本上,当我看到一个查询...
SELECT * FROM logs WHERE action = "Processed"
GROUP BY action HAVING MAX(log_time)
...我的假设是,根据代码的显示方式,它将检索具有最大log_time的行,其中action处理。这似乎是一个错误的假设。那么HAVING MAX()
甚至意味着什么?
答案 0 :(得分:4)
您需要为聚合函数包含GROUP BY子句。
SELECT MAX(log_time), user
FROM logs
WHERE action = "Processed"
GROUP BY user
或者,如果您要查找单个值,请不要包含用户:
SELECT MAX(log_time)
FROM logs
WHERE action = "Processed"
最后,如果您希望用户与该单个最大值相关联,请使用子查询
SELECT l.user, l.log_time
FROM logs l
INNER JOIN (SELECT MAX(log_time) as max_time
FROM logs
WHERE action = "Processed") q
ON l.log_time = q.max_time
AND l.action = "Processed"
答案 1 :(得分:1)
基于其他人的输入,特别是Damien_The_Unbeliever,我意识到我的问题是HAVING MAX()
实际上没有做任何事情。它只会将日期排除在外,因为它没有与任何东西进行比较。
当我说HAVING MAX(log_time)
时,它转换为HAVING 2011-03-03 08:59:33
,它不会告诉SQL它应该具有什么,它只是一个声明,如IF (5)
。我认为。 HAVING
对我来说仍然有些神秘,但我认为这就是为什么这个特殊问题让我感到悲伤的原因。
答案 2 :(得分:0)
我会按MAX(log_time)订购并选择前1名,因为无论如何都要进行排序。
答案 3 :(得分:0)
SELECT log_time, user
FROM logs
WHERE action = "Processed" && log_time=(select MAX(log_time) from logs)
)
这给出了输出
2011-03-03 08:59:33 5
答案 4 :(得分:0)
HAVING
- 子句用于不符合特定条件的过滤器组。您定义条件的方式是,“已处理”-group DOES与HAVING
子句匹配,因为其MAX(log_time)包含最大log_time(或许HAVING MAX(log_time)
计算结果为true。无论哪种方式,它都是一个奇怪的声明)......
你可能想要的是SELECT
最大log_time,在这种情况下查询将是:
SELECT MAX(log_time), user
FROM logs
WHERE action = "Processed"
GROUP BY action;
现在,您获得“1”作为用户的原因是用户列不是GROUP BY子句的一部分。这意味着MySQL不知道您在输出中需要哪个用户行。它可能是4行中的任何一行。因此,制定问题的另一种方法是:
SELECT logs.user, logs.log_time
FROM logs INNER JOIN
(SELECT MAX(log_time) as max, action
FROM logs
WHERE action = "Processed"
GROUP BY action) sub ON logs.log_time = sub.max AND logs.action = sub.action
注意:根据标准SQL,您提供的SQL查询作为示例不是有效的SQL查询。它适用于mysql,但这要归功于MySQL /如何实现GROUP BY。在标准SQL中,您唯一可以选择的是GROUP BY子句中提到的聚合函数和/或列的结果。
因此,在其他数据库系统中,您将无法选择user
- 列,因为它不是GROUP BY
- 列而不是聚合函数的结果。为了使它成为有效的标准SQL,您必须编写:
SELECT MAX(log_time), user
FROM logs
WHERE action = "Processed"
GROUP BY action, user -- Create groups based on both action AND user.
-- This allows us to SELECT the user column unambigiously.
;