MYSQL查询:最新时间戳+过去30分钟内唯一值

5

我需要从我的mysql表中检索具有唯一值的最新行。简单的表格布局是时间戳(now())和用户名列。该表每秒钟会获取新数据,我需要其中用户名唯一的最新行。

SELECT MAX(timestamp) as timestamp, username 
    FROM bla 
    WHERE timestamp < (now() - interval 30 minute) 
    GROUP BY username 
    ORDER BY timestamp DESC 

看起来这个查询没有返回最新的值,可能是因为该组正在执行我不想要的操作...


所以基本上您想要获取每个用户在最近30分钟内插入的最新行?此外,请注意timestamp是mysql中的保留字。您应该使用不同的名称来命名该字段,或者用反引号进行“转义”。 - Marc B
是的,你说得对,我的列使用另一个名称来表示时间戳值,这只是一个例子 :) 无论如何,谢谢你的提示! - HyperDevil
4个回答

6
如果您想查看最近30分钟的内容,那么我认为您需要使用“大于”而不是“小于”。
... WHERE timestamp > (now() - interval 30 minute) ...

+1 我正要点击提交,你打字速度真快。;-) - Ken White
哎呀,是的,我看到了那个,但结果仍然没有显示最新的值。 - HyperDevil
@HyperDevil:如果每秒插入2行数据,那么对于实时数据验证查询结果可能会很困难。 - Joe Stefanelli
我确实理解你的观点,但在我运行查询之前,我可以看到表格中有更新的结果。 - HyperDevil
@HyperDevil:你的“timestamp”列实际上是一个时间戳数据类型吗?我想知道转换到/从UTC是否存在问题? - Joe Stefanelli
显示剩余4条评论

3

虽然你所写的方法能够运行,但更快的解决方案是使用LEFT JOIN。在我正在处理的数据库中,使用LEFT JOIN实际上比使用其他方法快两倍,并且如果需要,可以获取最新行的所有列信息。

SELECT *
    FROM `bla`
    WHERE bla.created_at > (now() - interval 30 minute) AND (next_bla.created_at IS NULL)
    LEFT JOIN bla next_bla ON bla.username = next_bla.username AND bla.created_at < next_bla.created_at
    ORDER BY bla.created_at DESC

这个语句通过时间戳和相同的用户名将每一行与下一行匹配,并选择没有下一行的行(即next_bla.created_at IS NULL),也就是最近的行。

您还可以使用LIMIT子句来提高性能。

以下是一篇很好的文章,详细解释了GROUP BY的工作原理,用简单明了的语言: http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html

Andomar也提供了类似的答案-MySQL "Group By" and "Order By"


2
SELECT MAX(timestamp) as timestamp, username 
    FROM bla 
    WHERE timestamp > (now() - interval 30 minute) 
    GROUP BY username 
    ORDER BY timestamp DESC 

0

SELECT MAX(timestamp) as timestamp, username 
    FROM bla 
    WHERE timestamp > date_sub(now(), interval 30 minute) 
    GROUP BY username 
    ORDER BY timestamp DESC 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接