mysql查询某组中最新一条数据的列表(不用group by)

demo需求

业务主键相等的情况下 取某主键最新的一条数据,返回列表。
拿几条数据举个例子
image.png
标注的不全啊,把代表性的数据标了下,主要就是要红框框中的列表。

方法一 NOT EXISTS

SELECT t.id, t.source_primary_key, t.create_time FROM oydc_data_center t
	WHERE NOT EXISTS (
	SELECT t2.* FROM `oydc_data_center` t2
	WHERE t2.source_primary_key = t.source_primary_key
	AND t2.create_time > t.create_time
)

逻辑

主要逻辑就是,当外层每个主键调去匹配的时候,取外层时间大于内层时间存在的数据。这要时间小的数据自然而然过滤掉了。

效果

image.png

方法二 join + not in

SELECT t.id, t.source_primary_key, t.create_time FROM oydc_data_center t
WHERE id NOT IN (
	SELECT DISTINCT t1.id 
	FROM oydc_data_center t1
	LEFT JOIN oydc_data_center t2
	ON t1.source_primary_key = t2.source_primary_key
	WHERE t1.create_time < t2.create_time
)

逻辑

先将数据比较小的数据查出来,然后进行排除法,排除掉所有业务主键小的数据,最终就是每个业务主键中时间最新的数据啦。

效果

image.png

方法三(计数方式)

SELECT * 
 FROM ( 
 SELECT t.*, @row_number := IF(@row_source_pk = t.source_primary_key, @row_number+1, 1) AS rk, 
 @row_source_pk := t.source_primary_key FROM ( 
 SELECT t.* FROM oydc_data_center t 
ORDER BY t.source_primary_key, t.create_time DESC, t.id DESC ) t , 
 (SELECT @row_number := 0, @row_source_pk := '') c HAVING rk = 1 ) t 
 ORDER BY t.id 

方法四(开窗函数)

demo: 取每学科分数最高的那个。

CREATE TABLE `stu_score` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
  `stu_name` varchar(30) DEFAULT NULL COMMENT '学生姓名',
  `stu_no` varchar(30) DEFAULT NULL COMMENT '学号',
  `sub_type` tinyint DEFAULT NULL COMMENT '学科类型',
  `score` int DEFAULT NULL COMMENT '学生成绩',
  PRIMARY KEY (`id`),
  UNIQUE KEY `no_type` (`stu_no`,`sub_type`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生成绩表';

/*Data for the table `stu_score` */

insert  into `stu_score`(`id`,`stu_name`,`stu_no`,`sub_type`,`score`) values 
(1,'张三','23010101',1,60),
(2,'张三','23010101',2,67),
(3,'李四','23010102',1,54),
(4,'李四','23010102',2,76),
(5,'王五','23010103',1,99),
(6,'赵六','23010104',1,60);
SELECT * FROM (
SELECT *, row_number() over(PARTITION  BY sub_type ORDER BY `score` DESC) rk
FROM `stu_score`
)s
WHERE rk = 1

说两句

两种最终的效果都能达到的,但是建议使用第一种,第二种涉及到了表的连接,考虑到性能的话,建议使用第一种好一点。第二种方式不一定用left 也可以用inner。主要目的达到就可以了。

补充

最近用了1 2 两种方式,性能很差。到达10万条数据就顶不住了,又换了一种方式,利用了开窗函数,效果不错。还有一点,记得加上索引。

猜你喜欢

转载自blog.csdn.net/weixin_40741732/article/details/131328060