Seleccione las últimas n filas sin uso de order por cláusula

Quiero search las últimas n filas de una tabla en una database de Postgres. No quiero usar una cláusula ORDER BY porque quiero tener una consulta genérica. Alguien tiene alguna sugerencia?

Se apreciará una única consulta ya que no quiero usar el cursor FETCH de Postgres.

Que obtienes lo que esperas con la solución de Lukas (desde el 1 de noviembre de 2011) es pura suerte . No hay un "order natural" en un RDBMS por definición. Usted depende de los detalles de implementación que podrían cambiar con una nueva versión sin previo aviso. O un volcado / restauración podría cambiar ese order. Incluso puede cambiar de la nada cuando las statistics de DB cambian y el planificador de consultas elige un plan diferente que conduce a un order diferente de filas.

La forma correcta de get las "últimas n" filas es tener una columna de timestamp o secuencia y ORDER BY esa columna. Cada RDBMS que se te ocurra tiene ORDER BY , así que esto es tan "genérico" como se pueda.

Cito el manual aquí :

Si no se proporciona ORDER BY, las filas se devuelven en el order que el sistema encuentre más rápido para producir.

La solución de Lukas está bien para evitar LIMIT , que se implementa de manera diferente en varios RDBMS (por ejemplo, SQL Server usa TOP n lugar de LIMIT ), pero usted necesita ORDER BY en cualquier caso.

Puede valer la pena mencionar que, si bien las funciones de window están en el estándar SQL, todavía no son tan genéricas como podría desear. MySQL, por ejemplo, no los admite.

Use las funciones de window!

 select t2.* from ( select t1.*, row_number() over() as r, count(*) over() as c from ( -- your generic select here ) t1 ) t2 where t2.r + :n > t2.c 

En el ejemplo anterior, t2.r es el número de fila de cada fila, t2.c es el total de loggings en su selección genérica. Y :n serán las n últimas filas que desea recuperar. Esto también funciona cuando ordera su selección genérica.

EDITAR : Un poco less genérico de mi ejemplo anterior:

 select * from ( select my_table.*, row_number() over() as r, count(*) over() as c from my_table -- optionally, you could sort your select here -- order by my_table.a, my_table.b ) t where tr + :n > tc