选择最后n行而不使用order by子句

Mit*_*ani 5 sql postgresql sql-order-by

我想从Postgres数据库中的表中获取最后n行.我不想使用一个ORDER BY子句,因为我想要一个通用查询.有人有什么建议吗?

单个查询将被欣赏,因为我不想使用FETCHPostgres的光标.

Erw*_*ter 10

Lukas的解决方案(截至2011年11月1日)你得到了你所期望的纯粹的运气.有没有"自然秩序"中定义的RDBMS.您依赖于可能随新版本更改的实施细节,恕不另行通知.或者转储/恢复可以改变该顺序.当db统计信息发生更改并且查询计划程序选择导致不同行顺序的不同计划时,它甚至可以突然改变.

获取"最后n"行的正确方法是使用时间戳或序列列以及ORDER BY该列.你能想到的每一个RDBMS都有ORDER BY,所以这就像它的"通用"一样.

在这里引用手册:

如果未给出ORDER BY,则以系统发现最快生成的顺序返回行.

卢卡斯的解决方案是好的,以避免LIMIT,这是不同的各种RDBMS中实现(例如,SQL Server使用TOP n的替代LIMIT),但你必须ORDER BY在任何情况下.

值得一提的是,虽然窗口函数属于SQL标准,但它们仍然不像您希望的那样通用.例如,MySQL不支持它们.


Luk*_*der 5

使用窗口功能!

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
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,t2.r每行的行号t2.c是通用选择中的总记录.并且:n将是您要获取的最后几行.当您对通用选择进行排序时,这也适用.

编辑:我之前的例子有点不太通用:

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
Run Code Online (Sandbox Code Playgroud)