web-dev-qa-db-fra.com

Comment sélectionner l'ensemble le plus récent d'enregistrements datés d'une table mysql

Je stocke la réponse à divers appels rpc dans une table mysql avec les champs suivants:

Table: rpc_responses

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

PRIMARY KEY(timestamp,method,id)

Quelle est la meilleure méthode pour sélectionner les réponses les plus récentes pour toutes les combinaisons existantes de method et id?

  • Pour chaque date, il ne peut y avoir qu'une seule réponse pour une méthode/id donnée.

  • Toutes les combinaisons d'appels ne sont pas nécessairement présentes à une date donnée.

  • Il existe des dizaines de méthodes, des milliers d'identifiants et au moins 365 dates différentes

Exemples de données:

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 "....."

Résultat désiré:

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

(Je ne pense pas this est la même question - cela ne me donnera pas la plus récente response)

24
Ken

Répondu par moi-même, mais je ne suis pas sûr que ce sera une solution suffisamment efficace à mesure que la table grandira:

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);
14
Ken

Utilisez cette solution avec prudence:
il n'est pas garanti de fonctionner dans les futures versions de mysql
il n'est pas connu qu'il fonctionne dans la mariadb 5.5

Cette requête peut fonctionner correctement, car il n'y a pas de jointures.

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

Le "regroupement par" réduit le jeu de résultats sur la méthode et ne renvoie qu'une seule ligne par méthode, la plus récente, en raison de l'horodatage ORDER BY DESC dans la requête interne.

Pour info, PostgreSQL a un moyen de le faire intégré dans le langage:

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

Essaye ça...

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

... ça marche même dans Access!

6
versek

La sous-requête est très éprouvante lorsque l'ensemble de données devient plus grand.

Essaye ça:

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;
0
Simon

j'ai utilisé cela, travaillé pour moi

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