Original Address: https://codedefault.com/s/how-can-i-retrieve-the-last-record-in-each-group-mysql
Problem Description
For example, in MySQL
the database, data tables messages
and data records, as follows:
Id Name Other_Columns
-------------------------
1 A A_data_1
2 A A_data_2
3 A A_data_3
4 B B_data_1
5 B B_data_2
6 C C_data_1
If you perform MySQL
grouping query, as follows:
select * from messages group by name
All will be returned by name
the first data packet, as follows:
1 A A_data_1
4 B B_data_1
6 C C_data_1
So, how to query by name
the group return data in each of the last MySQL
sentence of it, the returned results are as follows:
3 A A_data_3
5 B B_data_2
6 C C_data_1
Option One
In MySQL
version 8.0 before you can use the following statement:
WITH ranked_messages AS (
SELECT m.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn FROM messages AS m ) SELECT * FROM ranked_messages WHERE rn = 1;
In MySQL
version 8.0, MySQL
adds support for window function (Window Functions), we can use window functions to simplify SQL
the query, and does not require the use GROUP BY
clause, as follows:
WITH ranked_messages AS (
SELECT m.*, ROW_NUMBER() OVER (PARTITION BY name ORDER BY id DESC) AS rn FROM messages AS m ) SELECT * FROM ranked_messages WHERE rn = 1;
Option II
Use MySQL
of the IN(...)
clause, as follows:
SELECT id, name, other_columns
FROM messages
WHERE id IN ( SELECT MAX(id) FROM messages GROUP BY name );
third solution
Use MySQL
of GROUP_CONCAT
and SUBSTRING_INDEX
to query, as follows:
SELECT
`Id`,
`Name`,
SUBSTRING_INDEX(
GROUP_CONCAT(
`Other_Columns` ORDER BY `Id` DESC SEPARATOR '||' ), '||', 1 ) Other_Columns FROM messages GROUP BY `Name`
Practice Code:
1 SELECT * from( 2 SELECT 3 ( @i := CASE WHEN @pre_parent_code = sem_shop_wangwang THEN @i + 1 ELSE 1 END ) rownum,t_sem_logs.*, 4 ( @pre_parent_code := sem_shop_wangwang ) 5 FROM 6 t_sem_logs, 7 ( SELECT @i := 0, @pre_parent_code := '' ) AS b 8 where sem_edit_time <= '2018-07-13' 9 GROUP BY 10 sem_shop_wangwang,id 11 ORDER BY sem_shop_wangwang desc,DATE_FORMAT(sem_edit_time,'%Y-%m-%d %H:%i:%s') DESC,sem_agree_state ASC 12 ) a where rownum = 1 GROUP BY sem_agree_state order by DATE_FORMAT(sem_edit_time,'%Y-%m-%d %H:%m:%s') DESC; 13