mysql consulta la lista de los últimos datos de un grupo (sin agrupar por)

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
imagen.png
. 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

imagen.png

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

imagen.png

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.

Supongo que te gusta

Origin blog.csdn.net/weixin_40741732/article/details/131328060
Recomendado
Clasificación