Возврат "последней" строки каждой "группы" в MySQL

Есть ли более эффективный способ сделать следующее?

select * 
    from foo as a
    where a.id = (select max(id) from foo where uid = a.uid group by uid)
    group by uid;
)

Этот ответ выглядит аналогичным, но является ли этот ответ лучшим способом сделать это - Как выбрать первую строку для каждой группы в MySQL?

Спасибо,

Крис.

P.S. таблица выглядит так:

CREATE TABLE foo (
    id INT(10) NOT NULL AUTO_INCREMENT,
    uid INT(10) NOT NULL,
    value VARCHAR(50) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `uid` (`uid`)
)

Данные:

id, uid, value
 1,   1, hello
 2,   2, cheese
 3,   2, pickle
 4,   1, world

результаты:

id, uid, value
 3,   2, pickle
 4,   1, world

Подробнее см. http://www.barricane.com/2012/02/08/mysql-select-last-matching-row.html.

Ответы

Ответ 1

Попробуйте этот запрос -

SELECT t1.* FROM foo t1
  JOIN (SELECT uid, MAX(id) id FROM foo GROUP BY uid) t2
    ON t1.id = t2.id AND t1.uid = t2.uid;

Затем используйте EXPLAIN для анализа запросов.


SELECT t1.* FROM foo t1
  LEFT JOIN foo t2
    ON t1.id < t2.id AND t1.uid = t2.uid
WHERE t2.id is NULL;

Ответ 2

Возврат последней строки каждого GROUP BY в MySQL с предложением WHERE:

SELECT *
FROM foo
WHERE id IN (
  SELECT Max(id)
  FROM foo
  WHERE value='XYZ'
  GROUP BY u_id
)
LIMIT 0,30

Ответ 3

если таблица имеет большой размер. Сделайте view содержащий все последние строки id

create view lastrecords as (select max(id) from foo where uid = a.uid group by uid)

Теперь присоединитесь к основному запросу с помощью view. Это будет быстрее.

  SELECT t1.* FROM tablename as t1
    JOIN lastrecords as  t2
    ON t1.id = t2.id AND t1.uid = t2.uid;

ИЛИ Вы также можете присоединиться к последним записям напрямую в запросе:

SELECT t1.* FROM tablename as t1
JOIN (SELECT uid, MAX(id) id FROM tablename GROUP BY id) as  t2
ON t1.id = t2.id AND t1.uid = t2.uid;

Ответ 4

Самый простой способ: вы можете выбрать выбранный список, который отсортирован.

SELECT * FROM (SELECT * FROM foo order by id DESC) AS footbl
group by uid
order by id DESC

Ответ 5

Это сработало для меня спасибо!

SELECT t1.* FROM foo t1
  JOIN (SELECT uid, MAX(id) id FROM foo GROUP BY uid) t2
    ON t1.id = t2.id AND t1.uid = t2.uid;

моя версия:

SELECT * FROM messages t1 JOIN (SELECT MAX(id) id FROM messages  where uid = 8279 and actv=1 GROUP BY uid ) t2 ON t1.id = t2.id ORDER BY datex desc LIMIT 0,10;

этот код ниже не возвращает все строки, которые я хочу, потому что если столбец max id является неактивным, он пропускает группу, даже если группа имеет активные строки.

select * from messages where uid = 8279 and actv=1 and id In (Select max(id) From messages Group By uid) order by datex desc;