mysql은 그룹의 최신 데이터 목록을 쿼리합니다(그룹 기준 없이).

데모 요구 사항

비즈니스 기본 키가 동일한 경우 특정 기본 키의 최신 데이터를 가져와 목록을 반환합니다.
몇 가지 데이터를 예로 들어보겠습니다
이미지.png
. 주석이 불완전합니다. 대표 데이터를 주로 빨간색 상자에 표시했습니다.

방법 1은 존재하지 않습니다

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
)

논리

주요 논리는 외부 레이어의 각 기본 키가 일치하도록 조정될 때 외부 시간이 내부 시간보다 큰 데이터를 취한다는 것입니다. 이 작업에는 약간의 시간이 걸리며 데이터는 자연스럽게 필터링됩니다.

효과

이미지.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
)

논리

먼저 상대적으로 작은 데이터가 있는 데이터를 찾은 후 소기업 기본 키가 있는 모든 데이터를 제외하는 제거 방법을 수행하여 최종적으로 각 기업 기본 키의 최신 데이터를 얻습니다.

효과

이미지.png

방법 3(계산 방법)

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 

방법 4(창 기능)

데모: 각 과목에서 가장 높은 점수를 받은 것을 선택하세요.

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

몇 마디 말해보세요

두 가지 최종 효과를 모두 얻을 수 있지만 첫 번째를 사용하는 것이 좋습니다. 두 번째는 테이블 연결과 관련된 것이므로 성능을 고려하면 첫 번째를 사용하는 것이 좋습니다. 두 번째 방법은 반드시 왼쪽을 사용할 필요는 없지만 내부를 사용할 수도 있습니다. 주요 목적이 달성되면 충분합니다.

다시 채우다

최근에 1번과 2번 두가지 방법을 써봤는데 성능이 많이 안좋습니다. 데이터가 10만개에 이르렀을 때 더 이상 참을 수 없어서 방법을 바꿔 윈도잉 기능을 사용해봤는데 잘 되더라구요. 한 가지 더, 색인을 추가하는 것을 잊지 마세요.

추천

출처blog.csdn.net/weixin_40741732/article/details/131328060