Come ottenere l’ultimo record in ogni gruppo utilizzando GROUP BY?

Diciamo che ho una tabella chiamata messages con le colonne:

 id | from_id | to_id | subject | message | timestamp 

Voglio ricevere solo l’ultimo messaggio da ciascun utente, come vedresti nella tua casella di posta di FaceBook prima di approfondire il thread attuale.

Questa query sembra avvicinarmi al risultato che mi serve:

 SELECT * FROM messages GROUP BY from_id 

Tuttavia la query mi sta dando il messaggio più vecchio da ogni utente e non il più recente.

Non riesco a capire questo fuori.

Dovresti trovare gli ultimi valori di timestamp in ogni gruppo (sottoquery) e poi unire questa subquery alla tabella –

 SELECT t1.* FROM messages t1 JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2 ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp; 

Prova questo

 SELECT * FROM messages where id in (SELECT max(id) FROM messages GROUP BY from_id ) order by id desc 

questa query restituisce l’ultimo record per ogni Form_id:

  SELECT m1.* FROM messages m1 LEFT JOIN messages m2 ON (m1.Form_id = m2.Form_id AND m1.id < m2.id) WHERE m2.id IS NULL; 

Questo è un problema standard.

Si noti che MySQL consente di omettere le colonne dalla clausola GROUP BY, che non è lo standard SQL, ma non si ottengono risultati deterministici in generale quando si utilizza la funzione MySQL.

 SELECT * FROM Messages AS M JOIN (SELECT To_ID, From_ID, MAX(TimeStamp) AS Most_Recent FROM Messages WHERE To_ID = 12345678 GROUP BY From_ID ) AS R ON R.To_ID = M.To_ID AND R.From_ID = M.From_ID AND R.Most_Recent = M.TimeStamp WHERE M.To_ID = 12345678 

Ho aggiunto un filtro su To_ID per abbinare ciò che è probabile che tu abbia. La query funzionerà senza di essa, ma restituirà molti più dati in generale. Non è necessario che la condizione sia dichiarata sia nella query nidificata che nella query esterna (l’ottimizzatore dovrebbe sospendere automaticamente la condizione), ma non può fare nulla per ripetere la condizione come mostrato.

Completando semplicemente ciò che ha detto Devart, il codice seguente non è ordinato in base alla domanda:

 SELECT t1.* FROM messages t1 JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages GROUP BY from_id) t2 ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp; 

La clausola “GROUP BY” deve essere nella query principale poiché è necessario prima riordinare “SOURCE” per ottenere il “raggruppamento” necessario:

 SELECT t1.* FROM messages t1 JOIN (SELECT from_id, MAX(timestamp) timestamp FROM messages ORDER BY timestamp DESC) t2 ON t1.from_id = t2.from_id AND t1.timestamp = t2.timestamp GROUP BY t2.timestamp; 

Saluti,

Devi ordinarli.

SELECT * FROM messages GROUP BY from_id ORDER BY timestamp DESC LIMIT 1