2009-01-12 21 views
23

sto Memorizzazione la risposta a varie chiamate RPC in una tabella mysql con i seguenti campi:Come selezionare la più recente serie di record datati da una tabella mysql

Table: rpc_responses 

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

PRIMARY KEY(timestamp,method,id) 

Qual è il miglior metodo di selezione del le risposte più recenti per tutte le combinazioni esistenti di method e id?

  • Per ogni data ci può essere solo una risposta per un metodo determinato/id.

  • Non tutte le combinazioni di chiamate sono necessariamente presenti per una data specifica.

  • Ci sono decine di metodi, migliaia di ID e almeno 365 date diverse

dati del campione:

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

risultato desiderato:

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

(I don 'penso che this è la stessa domanda - non mi darà il più recente response)

+0

manuale di MySQL ha un caso simile: [Le Righe impugnare la massima gruppo-saggio di una determinata colonna] (https: // dev.mysql.com/doc/refman/5.6/en/example-maximum-column-group-row.html) – cgaldiolo

risposta

13

Auto risposto, ma non sono sicuro che sarà una soluzione abbastanza efficace come la tabella cresce:

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

Per quanto ne so, devi usare una subquery per ottenere quello che vuoi. –

+2

scusa per averlo riavviato dopo tanto tempo, ma il 'max (timestamp)' nella subquery non dovrebbe avere un alias chiamato 'timestamp'? In caso contrario, mysql restituisce un errore: 'Errore SQL (1054): colonna 'timestamp' sconosciuta in 'from clause'', perché USING() richiede che entrambe le tabelle abbiano lo stesso nome di colonna (l'ho provato in mysql versione 5.1 e 5.5) . L'aggiunta dell'alias risolve il problema. – DiegoDD

-1

Il concetto di "più recente" è piuttosto vaga. Se si intende qualcosa come le 100 righe più recenti, è sufficiente aggiungere uno TOP(100) alla clausola SELECT.

Se si intende il "più recente" sulla base di una data più recente, allora si può solo fare

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

Voglio il record più recente per ciascuna combinazione di metodo/id. Non tutte le combinazioni vengono modificate con ogni timestamp quindi non posso specificare solo la data/ora più recente. – Ken

+2

HAVING max (timestamp) = timestamp mi dà un set vuoto – Ken

-2

... è più di un anno dopo, ma potrei aiutare qualcuno per selezionare tutte le query a partire dal più recente

SELECT * 
FROM rpc_responses 
ORDER BY timestamp DESC 
+4

Aggiungi una clausola 'limite 100' e hai la risposta migliore. –

+0

È stata richiesta la risposta più recente per ogni combinazione di id e metodo, in questo modo verranno fornite le risposte più recenti indipendentemente dall'ID e dal metodo. – Bastiaan

5

Prova questo ...

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 

... è ev it funziona in Access!

0

La sottoquery è molto onerosa quando il set di dati diventa più grande.

Prova questo:

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 meno che non manchi qualcosa che è necessario UTILIZZO ('metodo') sul tuo join? – Ken

+1

Query senza fine qui –

+0

Questo metodo funziona in modo ottimale durante la creazione di viste poiché le viste MySQL non consentono le sottoquery. – zDaniels

0

ho usato questo, ha funzionato per me

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

Questo può query può funzionare bene, perché non ci sono si unisce.

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 

Il "gruppo da", crolla il risultato impostato sul metodo e restituisce solo 1 riga per il metodo, il più recente, a causa della ORDER BY DESC timestamp nella query interna.

FYI, PostgreSQL ha un modo di fare questo costruito nella lingua:

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

Questo metodo sembra dipendere dal fatto che GROUP BY comprime le righe trovate in t1 solo alla prima. È garantito in MySQL? – mkoistinen

+1

Non standard SQL, ma sì, è garantito in MySQL. Ciò che garantisce è "ORDER BY timestamp DESC". Se qualcuno abilita la modalità "ONLY_FULL_GROUP_BY", tuttavia, smetterà di funzionare. vedi stackoverflow.com/a/9797138/461096 stackoverflow.com/a/1066504/461096 rpbouman.blogspot.com/2007/05/debunking-group-by-myths.html – velcrow

+0

Ottimi collegamenti! Grazie! – mkoistinen

Problemi correlati