2015-08-20 2 views
0

Предположим, у меня есть таблица 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'; 

Но я не хочу выдавать несколько запросов, но один, и я не хочу называть ручки.

Как я могу выполнить свой запрос?

+1

Возможный дубликат http://stackoverflow.com/questions/32059558/sql-how-to- select-a-row-having-a-column-with-max-value-group-by – k0pernikus

+1

За исключением того, что это MySQL * (whic h не имеет 'ROW_NUMBER()') *, и этот вопрос - Oracle. – MatBailie

ответ

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') 

Оптимизатор будет использовать макро-как-расширение, чтобы подтолкнуть, что, где положение вниз к вашему совокупного запроса, а также внешнего запроса.

+0

Я не получаю это решение для работы. Запрос действителен, но он возвращает 0 строк для меня. – k0pernikus

+0

Извините, я пропустил 'GROUP BY', попробуйте сейчас (http://sqlfiddle.com/#!9/3ededa/2) – MatBailie

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

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

+0

Вы выбираете' id', но не включаете его в 'GROUP BY'. Документация MySQL затем говорит, что возвращаемый 'id' является произвольным. Вы можете получить '1, a, 30', или вы можете получить' 2, a, 30', или вы можете получить '3, a, 30', никаких гарантий нет. * (С этой страницы: https://dev.mysql.com/doc/refman/5.1/en/group-by-handling.html 'Сервер может выбирать любое значение из каждой группы, поэтому, если они не совпадают , выбранные значения являются неопределенными. ') * – MatBailie

Смежные вопросы