2011-12-15 38 views
44

Nella tabella seguente, come faccio a ottenere il record più recente di id=1 in base alla colonna di accesso e non a tutti e 3 i record?MySQL: recupera il record più recente

+----+---------------------+---------+ 
| id | signin    | signout | 
+----+---------------------+---------+ 
| 1 | 2011-12-12 09:27:24 | NULL | 
| 1 | 2011-12-13 09:27:31 | NULL | 
| 1 | 2011-12-14 09:27:34 | NULL | 
| 2 | 2011-12-14 09:28:21 | NULL | 
+----+---------------------+---------+ 

risposta

53

Gruppi Usa l'aggregato MAX(signin) raggruppati per id. Questo elencherà il più recente signin per ogni id.

SELECT 
id, 
MAX(signin) AS most_recent_signin 
FROM tbl 
GROUP BY id 

per ottenere l'intera singolo record, eseguire un INNER JOIN contro un subquery che restituisce solo il MAX(signin) per id.

SELECT 
    tbl.id, 
    signin, 
    signout 
FROM tbl 
    INNER JOIN (
    SELECT id, MAX(signin) AS maxsign FROM tbl GROUP BY id 
) ms ON tbl.id = ms.id AND signin = maxsign 
WHERE tbl.id=1 
+0

Ecco cosa ha funzionato, sulla base di ** ** prima risposta: 'selezionare ID, MAX (signin) FROM tbl GROUP BY id WHERE id = 1;' – enchance

+0

ho cercato di implementare la soluzione di 2 ° (per ottenere il intera riga) sulla mia situazione personale, ma ottengo sempre un set di risultati vuoto – rantsh

+1

@rantsh Perché non era corretto! L'ho corretto sopra. –

46
SELECT * 
FROM tbl 
WHERE id = 1 
ORDER BY signin DESC 
LIMIT 1; 

L'indice evidente sarebbe il (id), o un multicolumn index su (id, signin DESC).

+5

Questo sembra il modo più pulito di farlo! – karancan

+0

Considera di creare un indice per la colonna di accesso, velocizzerà significativamente il processo –

+0

Usa 'SELEZIONA TOP 1 *' e rimuovi l'ultima riga 'LIMIT 1'. se si utilizza SQL Server. Utilizzare quanto sopra se MySQL o Postgres. – jaredbaszler

3
Select [insert your fields here] 
from tablename 
where signin = (select max(signin) from tablename where ID = 1) 
+3

** Non usare mai *, definire sempre i campi ** – zerkms

+4

@zerkms: ci sono situazioni in cui '*' è anche * preferibile *. È una questione di legame precoce rispetto al legame tardivo. –

+2

@Erwin Brandstetter: Ho cambiato la mia opinione dopo 2 anni, infatti, – zerkms

8

Sulla base di @ xQbert risposta, si può evitare il subquery e renderlo sufficientemente generico per filtrare per qualsiasi ID

SELECT id, signin, signout 
FROM dTable 
INNER JOIN(
    SELECT id, MAX(signin) AS signin 
    FROM dTable 
    GROUP BY id 
) AS t1 USING(id, signin) 
+0

Ciao come funziona questa query ed è più efficiente della risposta di xQbert? Entrambe le query vengono eseguite all'incirca nello stesso periodo per me e non capisco l'utilizzo della parte della query che sostituisce ciò che è di solito in uso. – ZJS

1
SELECT * FROM (SELECT * FROM tb1 ORDER BY signin DESC) GROUP BY id; 
+1

Questo non funziona. –

0

Ho avuto un problema simile. Avevo bisogno di ottenere l'ultima versione della traduzione del contenuto della pagina, in altre parole, per ottenere quel record specifico che ha il numero più alto nella colonna della versione. Quindi seleziono tutti i record ordinati per versione e poi prendo la prima riga dal risultato (usando la clausola LIMIT).

SELECT * 
FROM `page_contents_translations` 
ORDER BY version DESC 
LIMIT 1 
Problemi correlati