2010-04-08 7 views
29

Digamos que tengo la siguiente tabla de base de datos:¿Obtiene las últimas N filas en la base de datos en orden?

record_id | record_date | record_value 
-----------+-------------+-------------- 
     1 | 2010-05-01 |  195.00 
     2 | 2010-07-01 |  185.00 
     3 | 2010-09-01 |  175.00 
     4 | 2010-05-01 |  189.00 
     5 | 2010-06-01 |  185.00 
     6 | 2010-07-01 |  180.00 
     7 | 2010-08-01 |  175.00 
     8 | 2010-09-01 |  170.00 
     9 | 2010-10-01 |  165.00 

Quiero agarrar los últimos 5 filas con los datos ordenados por ASC record_date. Esto es fácil de hacer con:

SELECT * FROM mytable ORDER BY record_date ASC LIMIT 5 OFFSET 4 

Lo que me daría:

record_id | record_date | record_value 
-----------+-------------+-------------- 
     6 | 2010-07-01 |  180.00 
     7 | 2010-08-01 |  175.00 
     3 | 2010-09-01 |  175.00 
     8 | 2010-09-01 |  170.00 
     9 | 2010-10-01 |  165.00 

Pero, ¿cómo lo hago cuando no sé cuántos registros hay y no puedo calcular la magia número de 4?

que he probado esta consulta, pero si hay menos de 5 registros, que se traduce en un desplazamiento negativo, que no es válido:

SELECT * FROM mytable ORDER BY record_date ASC LIMIT 5 
    OFFSET (SELECT COUNT(*) FROM mytable) - 5; 

Entonces, ¿cómo lograr esto?

Respuesta

58

¿Por qué no ordena solo de la manera opuesta?

SELECT * FROM mytable ORDER BY record_date DESC LIMIT 5; 

Si no desea voltear hacia atrás correctamente en la aplicación, puede anidar una consulta y darles la vuelta dos veces:

SELECT * 
    FROM (SELECT * FROM mytable ORDER BY record_date DESC LIMIT 5) 
    ORDER BY record_date ASC; 

... lo que resulta ser una operación bastante barato .

+1

Por primera consulta: porque no quieren tener que solucionar el problema de la aplicación. Para la segunda consulta: funcionó a la perfección, pero no encaja bien en mi DAL. Oh bien. ¡Gracias! – Kristopher

+1

@Travis Segunda consulta da un error. La consulta anidada debe ir seguida de una declaración AS [query_name] antes de ORDER BY –

+1

@AndyStowAway: eso podría ser una limitación de su implementación. Estoy bastante seguro de que las subconsultas anónimas están bien (sé que funcionan en Postres y MySQL). –

9

Esto debería funcionar:

WITH t AS (
    SELECT * FROM mytable ORDER BY record_date DESC LIMIT 5 
) 
SELECT * FROM t ORDER BY record_date ASC; 
+0

sí, este es un gran complemento para la vuelta atrás. ¡Gracias! – zerocog

Cuestiones relacionadas