2009-08-20 21 views
5

Tome un vistazo a la tabla de MySQL a continuación llamados "artículos":encontrar la fila con el valor máximo de ID en MySQL

+----+-----------+---------+------------------------+--------------------------+ 
| id | articleId | version | title     | content     | 
+----+-----------+---------+------------------------+--------------------------+ 
| 1 |   1 | 0.0  | ArticleNo.1 title v0.0 | ArticleNo.1 content v0.0 | 
| 2 |   1 | 1.0  | ArticleNo.1 title v1.0 | ArticleNo.1 content v1.0 | 
| 3 |   1 | 1.5  | ArticleNo.1 title v1.5 | ArticleNo.1 content v1.5 | 
| 4 |   1 | 2.0  | ArticleNo.1 title v2.0 | ArticleNo.1 content v2.0 | 
| 5 |   2 | 1.0  | ArticleNo.2 title v1.0 | ArticleNo.2 content v1.0 | 
| 6 |   2 | 2.0  | ArticleNo.2 title v2.0 | ArticleNo.2 content v2.0 | 
+----+-----------+---------+------------------------+--------------------------+ 

Im tratando de llegar a una consulta para devolver Articles.id donde es Articles.version el número máximo.

La tabla de Artículos reales contiene más de 10,000 entradas.

Por lo tanto, en este ejemplo SÓLO quiero que devuelvan Articles.id 4 y 6. He estado buscando la palabra clave distinct y la función max(), pero no puedo encontrarla.

Cualquier sugerencia apreciados ...

Respuesta

4

Usted necesita una consulta sub aquí:

SELECT a.id, a.version 
FROM articles a 
WHERE a.version = (
    SELECT MAX(version) 
    FROM articles b 
    WHERE b.articleId = a.articleId 
) 
+0

Esto devuelve todas las últimas versiones de los artículos solamente, descartando las versiones anteriores/anteriores. Muchachos agradables de las consultas ¡muchas gracias! –

+0

Solo para el registro: T.J. Crowder señaló en su respuesta, que una subconsulta no es obligatoria: se puede hacer con un LEFT JOIN, también. – soulmerge

4

Se puede usar una sub consulta aquí:

select 
    a.id 
from 
    articles a 
where 
    a.version = (select max(version) from articles) 

Dado que esto no es una consulta correlacionada, será bastante rápido (tan rápido o más rápido que una unión), por lo que no tiene que preocuparse por eso. Pero devolverá todos los valores que tengan el máximo de articleid.

Por supuesto, recomendaría que arroje un índice en articleid (asumiendo que id ya está agrupado). Eso lo ayudará a regresar aún más rápido.

como se ha señalado en los comentarios, si desea obtener la versión máximo para cada articleid, puede hacer lo siguiente:

select 
    a.id 
from 
    articles a 
    inner join (select articleid, max(version) 
       from articles group by articleid) as b on 
     a.articleid = b.articleid 
     and a.version = b.version 

Esto creará una unión de ese sub consulta y por lo general mucho más rápido que una subconsulta correlacionada que selecciona el máximo para cada articleid.

+1

Esto no es correcto: esto selecciona que el ID máximo del artículo es máximo, no la versión del artículo. – tw39124

+0

@Tom: Sí, y ahora lo arreglé, así que está bien. – Eric

+0

Tenga en cuenta que esto solo seleccionará los artículos que tengan la * misma * versión. Si quiere buscar la última versión de * cada * artículo, eche un vistazo a mi respuesta a continuación. – soulmerge

1

SELECT Articles.id FROM Articles WHERE Articles.version IN (SELECT MAX(Articles.version) FROM Articles)

1

tal vez algo como:

seleccionar * de artículos en los que articleid en (select max (articleversion) de los artículos)

1

Usted puede hacer

SELECT articles.id 
    FROM articles a 
WHERE NOT EXISTS(SELECT * FROM articles a2 WHERE a2.version > a.version) 

I don' Sé que MySQL funcionará con él, pero Oracle y SQL Server están de acuerdo.

5

Desde el MySQL manual, esto hace el truco:

SELECT a1.id 
FROM Articles a1 
LEFT JOIN Articles a2 ON a1.articleId = a2.articleId AND a1.version < a2.version 
WHERE a2.articleId IS NULL; 

Ver el enlace de justificación.

+0

También tenga en cuenta que las subconsultas en la cláusula WHERE en MySQL se pueden ejecutar para cada fila en el resultado, por lo que esta es probablemente la mejor respuesta. –

1

Todas las respuestas anteriores pueden resolver el problema establecido de DJDonaL3000. Pero, la mayoría de ellos son sub consultas relacionadas que dificultan el rendimiento de la aplicación. Si está utilizando una aplicación en la nube, le sugiero que no use las consultas anteriores. La mejor manera entonces es mantener dos tablas, A y B. A que contengan siempre la última versión del artículo y B con detalles de todas las versiones. El problema es que habrá más actualizaciones e inserciones en las tablas, pero la recuperación será más rápida ya que solo necesita ejecutar una consulta de selección normal en la tabla A.Hacer un grupo by y max en una consulta interna le costará

Cuestiones relacionadas