2011-12-15 32 views
44

En la tabla a continuación, ¿cómo obtengo solo el registro más reciente de id=1 basado en la columna de inicio de sesión y no en los 3 registros?MySQL: obtener el registro más reciente

+----+---------------------+---------+ 
| 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 | 
+----+---------------------+---------+ 

Respuesta

53

usar la suma MAX(signin) agrupados por ID. Esto mostrará la lista más reciente de signin para cada id.

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

Para obtener todo el registro único, realizar una INNER JOIN contra una subconsulta que devuelve sólo el MAX(signin) por 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

Esto es lo que trabajó sobre la base de su primera ** ** respuesta: 'SELECT ID, MAX (signin) DE GRUPO POR TBL donde id = 1;' – enchance

+0

me trató de poner en práctica la segunda solución (para obtener el toda la fila) en mi propia situación, pero siempre obtengo un conjunto de resultados vacío – rantsh

+1

@rantsh ¡Porque era incorrecto! Lo he corregido arriba. –

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

El índice obvia sería en (id), o una multicolumn index en (id, signin DESC).

+5

¡Esta parece ser la forma más limpia de hacerlo! – karancan

+0

Considere la posibilidad de crear un índice para la columna de inicio de sesión, acelerará significativamente el proceso –

+0

Use 'SELECT TOP 1 *' y elimine 'LIMIT 1' last line. si usa SQL Server. Utilice lo anterior si MySQL o Postgres. – jaredbaszler

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

** Nunca use *, defina siempre los campos ** – zerkms

+4

@zerkms: Hay situaciones donde '*' es incluso * preferible *. Es una cuestión de unión temprana versus unión tardía. –

+2

@Erwin Brandstetter: He cambiado mi opinión después de 2 años de hecho – zerkms

8

Sobre la base de @ xQbert respuesta, se puede evitar la subconsulta y que sea lo suficientemente genérico para filtrar por cualquier 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

Hola, ¿cómo funciona esta consulta y es más eficiente que la respuesta de xQbert? Ambas consultas se ejecutan casi al mismo tiempo para mí y no entiendo que el uso de la parte de la consulta reemplace lo que es habitual y activo. – ZJS

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

Esto no funciona. –

0

tuve un problema similar. Necesitaba obtener la última versión de la traducción del contenido de la página, en otras palabras, para obtener ese registro específico que tiene el número más alto en la columna de la versión. Así que selecciono todos los registros ordenados por versión y luego tomo la primera fila del resultado (usando la cláusula LIMIT).

SELECT * 
FROM `page_contents_translations` 
ORDER BY version DESC 
LIMIT 1 
Cuestiones relacionadas