requisitos de demostración
Si las claves primarias comerciales son iguales, obtenga los datos más recientes de una determinada clave primaria y devuelva la lista.
Tomemos algunos datos como ejemplo
. La anotación está incompleta. He marcado los datos representativos, principalmente la lista en el cuadro rojo.
Método 1NO EXISTE
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
)
lógica
La lógica principal es que cuando cada clave primaria en la capa externa se ajusta para que coincida, se toman los datos cuyo tiempo externo es mayor que el tiempo interno. Esto lleva un poco de tiempo y los datos se filtran de forma natural.
Efecto
Método 2 unirse + no participar
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
)
lógica
Primero, busque datos con datos relativamente pequeños, luego realice el método de eliminación para excluir todos los datos con claves primarias de pequeñas empresas y, finalmente, obtenga los datos más recientes en cada clave primaria de negocios.
Efecto
Método tres (método de conteo)
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
Método 4 (función de ventana)
demo: Toma el que tenga mayor puntuación en cada materia.
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
Di algunas palabras
Se pueden lograr ambos efectos finales, pero se recomienda utilizar el primero. El segundo implica la conexión de la mesa. Teniendo en cuenta el rendimiento, se recomienda utilizar el primero. El segundo método no necesariamente usa left sino que también puede usar internal. Es suficiente si se logra el objetivo principal.
Reponer
Recientemente utilicé dos métodos, 1 y 2, y el rendimiento es muy pobre. Cuando alcanzó los 100.000 datos, no pude soportarlo más, así que cambié el método y utilicé la función de ventanas, que funcionó bien. Una cosa más, recuerda agregar un índice.