2011-04-05 13 views
26

Tengo una tabla de base de datos que contiene las siguientes columnas:último conjunto distinto de registros

id code value datetime timestamp 

En esta tabla los únicos valores únicos residen en ID de clave primaria, es decir.

Deseo recuperar el último conjunto distinto de registros en esta tabla en función del valor de fecha y hora. Por ejemplo, digamos que a continuación es mi mesa

id code value datetime    timestamp 
1 1023 23.56 2011-04-05 14:54:52 1234223421 
2 1024 23.56 2011-04-05 14:55:52 1234223423 
3 1025 23.56 2011-04-05 14:56:52 1234223424 
4 1023 23.56 2011-04-05 14:57:52 1234223425 
5 1025 23.56 2011-04-05 14:58:52 1234223426 
6 1025 23.56 2011-04-05 14:59:52 1234223427 
7 1024 23.56 2011-04-05 15:00:12 1234223428 
8 1026 23.56 2011-04-05 15:01:14 1234223429 
9 1025 23.56 2011-04-05 15:02:22 1234223430 

Quiero recuperar los registros con los ID 4, 7, 8 y 9 es decir, el último conjunto de registros con códigos distintos (basados ​​en el valor de fecha y hora). Lo que he resaltado es simplemente un ejemplo de lo que estoy tratando de lograr, ya que esta tabla eventualmente contendrá millones de registros y cientos de valores de código individuales.

¿Qué instrucción SQL puedo usar para lograr esto? Parece que no puedo hacerlo con una sola instrucción SQL. Mi base de datos es MySQL 5.

Respuesta

50

Esto debería funcionar para usted.

SELECT * 
FROM [tableName] 
WHERE id IN (SELECT MAX(id) FROM [tableName] GROUP BY code) 

Si la identificación es AUTO_INCREMENT, no hay necesidad de preocuparse acerca de la fecha y hora que es mucho más caro para calcular, como el más reciente de fecha y hora también tendrá el más alto ID.

Actualización: Desde el punto de vista de rendimiento, asegúrese de que los id y code columnas se indexan cuando se trata de un gran número de registros. Si id es la clave principal, está incorporada, pero es posible que deba agregar un índice no agrupado que cubra code y id.

+1

+1 para evitar las pruebas de fecha y hora si se autoincrementó ... Me tomé la libertad de volver a formatear la respuesta. – krtek

+0

¡Funciona como un encanto! Muchas gracias por esto. –

+1

@smdrager, Very Nice ... salvó mi tiempo. – vissu

0

Voy a intentar algo como esto:

select * from table 
where id in (
    select id 
    from table 
    group by code 
    having datetime = max(datetime) 
) 

(responsabilidad, esto no se ha probado)

Si la fila con la fecha y hora más grande también tiene el id más grande, la solución propuesta por smdrager es más rápido

5

Prueba esto:

SELECT * 
    FROM <YOUR_TABLE> 
WHERE (code, datetime, timestamp) IN 
(
    SELECT code, MAX(datetime), MAX(timestamp) 
    FROM <YOUR_TABLE> 
    GROUP BY code 
) 
+0

Dado que la tabla tiene una clave principal, no es necesario que hagas una cláusula where complicada. ver mi respuesta – krtek

+0

@Krtek: de acuerdo, pero eso requiere suponer que el ID es un incremento automático. – Chandu

+0

en absoluto, la respuesta de smdrager sí, la subconsulta en la mía devuelve la buena identificación para usar debido a la cláusula 'having' – krtek

1

Es y viejo poste de, pero las pruebas @smdrager respuesta con tablas de gran tamaño era muy lento. Mi solución a esto fue el uso de "unión interna" en lugar de "donde en".

SELECT * 
FROM [tableName] as t1 
INNER JOIN (SELECT MAX(id) as id FROM [tableName] GROUP BY code) as t2 
ON t1.id = t2.id 

Esto funcionó muy rápido.

+0

Gracias. Lo probaré cuando vuelva a necesitar usar esto. –

Cuestiones relacionadas