1、需求
最近有个需求就是去重获取MySQL中企业的报表数据,同一个企业的报表可以有多个,获取最新的报表数据,这里数据库的版本是8.0。
这里模拟下需求,创建数据库表 test :
create table test
(
id int auto_increment primary key,
name varchar(100) null,
age int null,
create_time datetime null,
update_time timestamp default CURRENT_TIMESTAMP null
);
并写入重复数据:
INSERT INTO test (id, name, age, create_time, update_time)
VALUES (1, 'zhangsan', 12, '2022-03-17 17:39:56', '2022-03-17 17:39:56');
INSERT INTO test (id, name, age, create_time, update_time)
VALUES (2, 'zhangsan', 14, '2022-03-17 17:39:58', '2022-03-17 17:39:58');
INSERT INTO test (id, name, age, create_time, update_time)
VALUES (3, 'lisi', 19, '2022-03-17 17:39:57', '2022-03-17 17:39:57');
这里name字段代表重复,age 或者 id 用来测试时哪条数据,使用 create_time 验证最新数据。
2、尝试验证
- 方式1: 分组获取,使用group by
select id,name, age,create_time,update_time
from test
group by name
order by update_time
以上你会发现 MySQL 5.X 是可以执行的,但是 MySQL 8.0 之后不能执行了。
这里MySQL 5.X 获取的是分组前的第一条数据,但是这种写法是有问题的,不符合。
大家使用的时候,也要主要一些语法在5.X 可以执行,但是8.0之后就无法执行了。
- 方式2:子查询获取id,并通过主键查询
这里的前提是id自增,所以获取最大的id即为最新数据。
select *
from test
where id in (
select max(id)
from test
group by name)
也可以使用这种写法:
select t1.*
from test t1,(
select max(id) as id
from test
group by name) t2
where t1.id = t2.id
执行结果集:
3、总结
总体思路还是通过 获取最大时间的主键值,然后通过主键查询到具体数据。
当然假如只需要对名称去重就比较简单只需要使用 select distinct name from test 即可。
假如不想用SQL解决,在代码中处理也是可以的,例如使用Java 就可以先进行分组排序,然后获取最大时间的一条数据即可。