如何从mysql表中选择最新的日期记录集

Ken*_*Ken 25 mysql sql date greatest-n-per-group

我将响应存储在mysql表中的各种rpc调用中,其中包含以下字段:

Table: rpc_responses

timestamp   (date)
method      (varchar)
id          (varchar)
response    (mediumtext)

PRIMARY KEY(timestamp,method,id)
Run Code Online (Sandbox Code Playgroud)

什么是选择最近期的所有现有组合响应的最佳方法methodid

  • 对于每个日期,给定方法/ id只能有一个响应.

  • 并非所有呼叫组合都必须存在于给定日期.

  • 有许多方法,数千个ID和至少365个不同的日期

样本数据:

timestamp  method  id response
2009-01-10 getThud 16 "....."
2009-01-10 getFoo  12 "....."
2009-01-10 getBar  12 "....."
2009-01-11 getFoo  12 "....."
2009-01-11 getBar  16 "....."
Run Code Online (Sandbox Code Playgroud)

期望的结果:

2009-01-10 getThud 16 "....."
2009-01-10 getBar 12 "....."
2009-01-11 getFoo 12 "....."
2009-01-11 getBar 16 "....."
Run Code Online (Sandbox Code Playgroud)

(我不认为是同一个问题 - 它不会给我最新的response)

vel*_*row 28

谨慎使用此解决方案:
不保证在未来的mysql版本中
可以使用它不知道在mariadb 5.5中工作

这可以查询可能表现良好,因为没有连接.

SELECT * FROM (
    SELECT timestamp, method, id, response
    FROM rpc_responses
    WHERE 1 # some where clause here
    ORDER BY timestamp DESC
) as t1
GROUP BY method
Run Code Online (Sandbox Code Playgroud)

"group by"会折叠方法上的结果集,并且每个方法只返回1行,最新的一行,因为内部查询中的ORDER BY时间戳DESC.

仅供参考,PostgreSQL有一种方法可以在语言中构建:

SELECT DISTINCT ON (method) timestamp, method, id, response
FROM rpc_responses
WHERE 1 # some where clause here
ORDER BY method, timestamp DESC
Run Code Online (Sandbox Code Playgroud)

  • 这是错的.从[MySQL手册](https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html):"服务器可以自由选择每个组中的任何值,所以除非它们是同样,选择的值是不确定的.此外,添加ORDER BY子句不会影响每个组的值的选择.在选择值之后会对结果集进行排序,并且ORDER BY不会影响每个值中的值.服务器选择的组." (9认同)
  • 此方法似乎取决于GROUP BY将t1中找到的行折叠为仅第一个的事实.这在MySQL中有保证吗? (5认同)
  • @cgaldiolo在这里是正确的!这是一个可怕的答案!不能保证这在当前 MySQL 版本的所有情况下都有效,更不用说任何未来版本了。 (2认同)

Ken*_*Ken 14

自我回答,但我不确定随着表格的增长,它将是一个足够有效的解决方案:

SELECT timestamp,method,id,response FROM rpc_responses 
INNER JOIN
(SELECT max(timestamp),method,id FROM rpc_responses GROUP BY method,id) latest
USING (timestamp,method,id);
Run Code Online (Sandbox Code Playgroud)

  • 很抱歉在这么久之后恢复它,但子查询中的`max(timestamp)`是否应该有一个名为`timestamp`的别名?否则,mysql会出现错误:`SQL Error(1054):'from clause'中的未知列'timestamp',因为USING()要求两个表具有相同的列名(我在mysql版本5.1和5.5中尝试过) .添加别名可以解决问题. (2认同)

小智 6

试试这个...

SELECT o1.id, o1.timestamp, o1.method, o1.response   
FROM rpc_responses o1
WHERE o1.timestamp = ( SELECT max(o2.timestamp)
                       FROM rpc_responses o2
                       WHERE o1.id = o2.id )
ORDER BY o1.timestamp, o1.method, o1.response
Run Code Online (Sandbox Code Playgroud)

......它甚至适用于Access!