2009-01-12 18 views
23

estoy almacenando la respuesta a varias llamadas RPC en una tabla de MySQL con los siguientes campos:¿Cómo seleccionar el más reciente conjunto de registros que datan de una tabla de MySQL

Table: rpc_responses 

timestamp (date) 
method  (varchar) 
id   (varchar) 
response (mediumtext) 

PRIMARY KEY(timestamp,method,id) 

¿Cuál es el mejor método de selección de la las respuestas más recientes para todas las combinaciones existentes de method y id?

  • Para cada fecha, solo puede haber una respuesta para un método/ID determinado.

  • No todas las combinaciones de llamadas están necesariamente presentes para una fecha determinada.

  • Hay docenas de métodos, miles de ids y al menos 365 fechas diferentes

datos de la muestra:

timestamp method id response 
2009-01-10 getThud 16 "....." 
2009-01-10 getFoo 12 "....." 
2009-01-10 getBar 12 "....." 
2009-01-11 getFoo 12 "....." 
2009-01-11 getBar 16 "....." 

resultado deseado:

2009-01-10 getThud 16 "....." 
2009-01-10 getBar 12 "....." 
2009-01-11 getFoo 12 "....." 
2009-01-11 getBar 16 "....." 

(i don 't think this es la misma pregunta - no me dará la más reciente response)

+0

manual de MySQL tiene un caso similar: [Las filas que tienen el máximo grupo que tienen de determinada columna] (https: // dev.mysql.com/doc/refman/5.6/en/example-maximum-column-group-row.html) – cgaldiolo

Respuesta

13

auto respondió, pero no estoy seguro de que será una solución lo suficientemente eficiente como la tabla crece:

SELECT timestamp,method,id,response FROM rpc_responses 
INNER JOIN 
(SELECT max(timestamp),method,id FROM rpc_responses GROUP BY method,id) latest 
USING (timestamp,method,id); 
+1

Hasta donde yo sé, debe usar una subconsulta para obtener lo que desea. –

+2

perdón por revivir esto después de tanto tiempo, pero ¿no debería el 'max (timestamp)' en la subconsulta tener un alias llamado 'timestamp'? De lo contrario, mysql da un error: 'SQL Error (1054): columna desconocida 'timestamp' en 'from clause'', porque USING() requiere que ambas tablas tengan los mismos nombres de columna (lo probé en mysql versión 5.1 y 5.5) . Agregar el alias resuelve el problema. – DiegoDD

-1

El concepto de "más reciente" es bastante vago. Si te refieres a algo así como las 100 filas más recientes, puedes agregar un TOP(100) a tu SELECT cláusula.

Si se refiere a la "más reciente" basado en una fecha más reciente, entonces puede simplemente hacer

SELECT timestamp,method,id,response 
FROM rpc_responses 
HAVING max(timestamp) = timestamp 
+1

Quiero el registro más reciente para cada combinación de método/identificación. No todas las combinaciones se cambian con cada marca de tiempo, así que no puedo especificar la última marca de tiempo. – Ken

+2

HAVING max (timestamp) = timestamp me da un conjunto vacío – Ken

-2

... es más de un año después, sino que puede ayudar a alguien para seleccionar todas las consultas a partir de la última

SELECT * 
FROM rpc_responses 
ORDER BY timestamp DESC 
+4

Agregue una cláusula 'límite 100' y usted tiene la mejor respuesta. –

+0

Se solicitó la respuesta más reciente para cada combinación de identificación y método, esto solo le proporcionará las respuestas más recientes independientemente de la identificación y el método. – Bastiaan

5

probar este ...

SELECT o1.id, o1.timestamp, o1.method, o1.response 
FROM rpc_responses o1 
WHERE o1.timestamp = (SELECT max(o2.timestamp) 
         FROM rpc_responses o2 
         WHERE o1.id = o2.id) 
ORDER BY o1.timestamp, o1.method, o1.response 

... es ev ¡trabaja en Access!

0

La subconsulta es muy complicada cuando el conjunto de datos aumenta.

Prueba esto:

SELECT t1.* 
FROM rpc_responses AS t1 
INNER JOIN rpc_responses AS t2 
GROUP BY t1.method, t1.id, t1.timestamp 
HAVING t1.timestamp=MAX(t2.timestamp)  
ORDER BY t1.timestamp, t1.method, t1.response; 
+1

a menos que me falta algo que necesita USING ('method') en su unión? – Ken

+1

Consulta interminable aquí –

+0

Este método funciona mejor cuando se crean vistas porque las vistas de MySQL no permiten subconsultas. – zDaniels

0

He utilizado este, trabajado para mí

select max(timestamp),method,id from tables where 1 group by method,id order by timestamp desc 
29

Use this solution with caution:
it is not guaranteed to work in future versions of mysql
it is not known to work in mariadb 5.5

Esto puede consulta puede realizarse bien, porque no hay une.

SELECT * FROM (
    SELECT timestamp, method, id, response 
    FROM rpc_responses 
    WHERE 1 # some where clause here 
    ORDER BY timestamp DESC 
) as t1 
GROUP BY method 

El "grupo por", colapsa el conjunto de resultados en el método, y devuelve sólo 1 fila por cada método, el más reciente, debido a la ORDER BY DESC marca de tiempo en la consulta interna.

FYI, PostgreSQL tiene una manera de hacer esto integrado en el lenguaje:

SELECT DISTINCT ON (method) timestamp, method, id, response 
FROM rpc_responses 
WHERE 1 # some where clause here 
ORDER BY method, timestamp DESC 
+5

Este método parece depender del hecho de que GROUP BY colapsará las filas encontradas en t1 solo a la primera. ¿Esto está garantizado en MySQL? – mkoistinen

+1

No SQL estándar, pero sí, está garantizado en MySQL. Lo que garantiza es el "ORDEN POR marca de tiempo DESC". Si alguien activa el modo 'ONLY_FULL_GROUP_BY', dejará de funcionar. ver stackoverflow.com/a/9797138/461096 stackoverflow.com/a/1066504/461096 rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html – velcrow

+0

¡Grandes enlaces! ¡Gracias! – mkoistinen

Cuestiones relacionadas