Select last n rows without use of order by clause

后端 未结 2 1208
春和景丽
春和景丽 2021-01-13 07:15

I want to fetch the last n rows from a table in a Postgres database. I don\'t want to use an ORDER BY clause as I want to have a generic query. Anyone has any s

相关标签:
2条回答
  • 2021-01-13 07:26

    Use window functions!

    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
    

    In the above example, t2.r is the row number of every row, t2.c is the total records in your generic select. And :n will be the n last rows that you want to fetch. This also works when you sort your generic select.

    EDIT: A bit less generic from my previous example:

    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 t.r + :n > t.c
    
    0 讨论(0)
  • 2021-01-13 07:47

    That you get what you expect with Lukas' solution (as of Nov. 1st, 2011) is pure luck. There is no "natural order" in an RDBMS by definition. You depend on implementation details that could change with a new release without notice. Or a dump / restore could change that order. It can even change out of the blue when db statistics change and the query planner chooses a different plan that leads to a different order of rows.

    The proper way to get the "last n" rows is to have a timestamp or sequence column and ORDER BY that column. Every RDBMS you can think of has ORDER BY, so this is as 'generic' as it gets.

    I quote the manual here:

    If ORDER BY is not given, the rows are returned in whatever order the system finds fastest to produce.

    Lukas' solution is fine to avoid LIMIT, which is implemented differently in various RDBMS (for instance, SQL Server uses TOP n instead of LIMIT), but you need to ORDER BY in any case.

    It may be worth mentioning that while window functions are in the SQL standard, they still aren't as generic as you might wish. MySQL, for instance, does not support them.

    0 讨论(0)
提交回复
热议问题