如何查询具有唯一标识符的行及其各自的最大值?

时间:2015-08-20 14:00:07

标签: mysql sql select max

假设我有表exection_records,其中包含数据:

+----+----------+---------------------+
| id | handle   | finishedAt          |
+----+----------+---------------------+
| 1  | task_foo | 2015-08-16 03:10:33 |
| 2  | task_foo | 2015-08-15 04:00:27 |
| 3  | task_foo | 2015-08-14 02:10:25 |
| 4  | task_bar | 2015-08-17 03:00:25 |
| 5  | task_bar | 2015-08-16 02:01:25 |
| 6  | task_bar | 2015-08-13 06:02:50 |
+----+----------+---------------------+

现在我希望finishedAt所在的行位于每个唯一句柄的最新时间戳,即:

+----+----------+---------------------+
| id | handle   | finishedAt          |
+----+----------+---------------------+
| 1  | task_foo | 2015-08-16 03:01:33 |
| 4  | task_bar | 2015-08-17 03:00:25 |
+----+----------+---------------------+

我知道MySQL中有MAX

我可以通过以下方式获取每项任务的最新记录:

SELECT *,MAX(finishedAt) FROM db.execution_records where taskHandle = 'task_foo';
SELECT *,MAX(finishedAt) FROM db.execution_records where taskHandle = 'task_bar';

然而,我不想发出多个查询,只有一个,我不想命名句柄。

我怎样才能实现我的查询?

3 个答案:

答案 0 :(得分:1)

在MySQL中,最简单的方法是使用一个子查询来查找每个句柄的最后完成时间,然后将这些结果重新加入到您的表中以挑选整行。

SELECT
  execution_records.*
FROM
(
  SELECT
    handle, MAX(finished_at) AS max_finished_at
  FROM
    execution_records
  GROUP BY
    handle
)
  AS summary
INNER JOIN
  execution_records
    ON  execution_records.handle      = summary.handle
    AND execution_records.finished_at = summary.max_finished_at

您仍然可以使用简单的WHERE子句将其过滤到特定句柄(而不是所有句柄)

WHERE
  summary.handle IN ('task_foo','task_bah')

然后,优化器将使用类似宏的扩展将where子句推送到聚合查询以及外部查询。

答案 1 :(得分:0)

select * 
  from exection_records 
  join (select handle, max(finishedAt) max 
          from exection_records 
        group by handle) m 
    on exection_records.finishedAt=max

Demo on sqlfiddle

答案 2 :(得分:0)

select id, handle, max(finishedAt) from exection_records group by handle;

这是输出

create table exection_records (id INT, handle VARCHAR(20), finishedAt BIGINT);


insert into exection_records values(1, 'a', 10);
insert into exection_records values(2, 'a', 20);
insert into exection_records values(3, 'a', 30);
insert into exection_records values(4, 'b', 15);
insert into exection_records values(5, 'b', 25);
insert into exection_records values(6, 'b', 35);

select id, handle, max(finishedAt) from exection_records group by handle;

id  handle  max(finishedAt)
1   a   30
4   b   35

SqlFiddle demo