2013-01-23 8 views
7

Sto tirando fuori alcune conversazioni dal mio database. Sono raggruppati nella colonna user_from.Ottieni l'ultima voce utilizzando GROUP BY

A partire da ora, emette il messaggio più vecchio. Voglio che mostri il messaggio più recente.

Qual è il modo più semplice per farlo?

SELECT * 
FROM (`mail`) 
JOIN `users` ON `users`.`id` = `mail`.`user_from` 
JOIN `users_info` ON `users_info`.`user_id` = `mail`.`user_from` 
WHERE `user_to` = '1' 
GROUP BY `user_from` 
ORDER BY `mail`.`date` desc 

tabella posta

enter image description here

tabella utente (frammento)

enter image description here

Questo è il codice di lavoro corrente. Il SecretAgent ha inviato un messaggio recente di posta presso l'agenzia che si dovrebbe mostrare invece enter image description here

+4

@xQbert Perché ?, il messaggio più recente è quello con la data massima – Lamak

+0

Supponendo che la posta sia un ID, perché non si ordina per 'mail.id desc'? o le e-mail inserite da luoghi diversi e l'id più alto non è necessario la nuova e-mail? – SERPRO

+0

Questo non farà il trucco, seleziona ancora il * più vecchio * uno –

risposta

4

MySQL è purtroppo molto indulgenti sul contenuto della clausola GROUP BY, che produce risultati inaffidabili a meno di includere tutti colonne nel GROUP BY. Non è mai consigliato a SELECT * in una query di join, ma lo lasceremo per ora. Quello che devi fare è eseguire un join di subquery che ottenga per la data il messaggio più recente per l'utente, unito al resto delle colonne.

SELECT 
    /* Don't actually do this. Be explicit about columns and assign aliases where their names collide */ 
    users.*, 
    users_info.*, 
    mail.* 
FROM 
    `users` 
    JOIN `mail` ON `users`.`id` = `mail`.`user_from` 
    JOIN `users_info` ON `users_info`.`user_id` = `mail`.`user_from` 
    /* Joined subquery gets most recent message from each user */ 
    JOIN (
    SELECT user_from, MAX(date) AS date 
    FROM mail 
    WHERE user_to = '1' 
    GROUP BY user_from 
    /* Joined back to the main mail table on user_from and date */ 
) most_recent ON mail.user_from = most_recent.user_from AND mail.date = most_recent.date 
    WHERE `user_to` =  '1' 

Modifica aggiornata per mostrare tutti i mittenti più recenti piuttosto che uno solo.

+0

Sembra funzionare quando lo si esegue in PHPMyAdmin. Ora mi limiterò a immergermi nei documenti di CodeIgniter e vedere come posso farlo utilizzando Active Records. Grazie! :-) –

+0

+1 per * sfortunatamente *. Lancia una festa per festeggiare 100k? – Kermit

+0

@njk Spero solo di rimanere attivo - non rispondo più a molti. alcuni sembrano "ritirati" a 100k. Sono forse 3 giorni di distanza ... –