Мне нужно получить данные из таблицы, сгруппированной по одному столбцу и упорядоченной другим столбцом. Обычно, когда вы выполняете GROUP BY по таблице, она будет извлекать первую строку в этой группе. Но моя задача состояла в том, чтобы получить последнюю строку в этой группе.
Я беру пример примера таблицы WordPress. Подумайте, что нам нужно получить данные из таблицы wp_posts
сгруппированные по полям post_type
и по убыванию, упорядоченные по ID
. С первой попытки я выполнил запрос, как показано ниже.
SELECT ID, post_type FROM wp_posts GROUP BY post_type ORDER BY ID DESC;
Я думал, что это правильно, но это не так. Проверьте ниже изображение для данных, которые я получил с помощью этого запроса.
Id | post_type................................................................................................
65 | attachment........................................................................................
2 | nav_menu_item.......................................................................................
187 | page ........................................................................................................
1897| post.......................................................................................................
Я также пробовал это после нескольких Googling, который работал для некоторых, но не работал для меня
SELECT subtable.ID, subtable.post_type FROM
(SELECT * FROM wp_posts ORDER BY ID DESC) AS subtable
GROUP BY post_type
В результате я хотел
Id | post_type.................................................................................................
1900| attachment..................................................................................
1672| nav_menu_item.................................................................................
1668| page...............................................................................................
1899| post..................................................................................................
Я думаю, что проблема заключается в том, что временная таблица возвращает порядок, сортируя при использовании GROUP BY.
Вы должны использовать:
SELECT *
FROM messages m1
WHERE message_id = (SELECT message_id
FROM messages m2
WHERE m1.user_id = m2.user_id
ORDER BY created_at DESC
LIMIT 1);
Или если у вас MySQL 8.0 простой ROW_NUMBER
:
SELECT *
FROM (SELECT *
,ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY created_at DESC) rn
FROM messages) sub
WHERE sub.rn = 1
LIMIT 1
вы можете использовать =
вместо IN
. На самом деле MySQL даже не поддерживает условия IN
с LIMIT
в подзапросе. В противном случае было бы слишком легко решить проблему «Top N на группу» :-)