如何在Oracle SQL中选择最新的一条数据并按日期排序?

14

如何在Oracle中选择前1条记录,这个问题有一个明确的答案(参见链接)

select * from table_name where rownum = 1

如何按日期降序排列:

select * from table_name order by trans_date desc

但它们不能一起工作(rownum不是根据trans_date生成的):

... where rownum = 1 order by trans_date desc

问题是如何选择最新的一项并按日期排序?


@MT0,这不是与“如何在Oracle中执行top 1?”和“Oracle选择前10条记录”重复的问题,因为它们只涉及查询结果中有限数量的行,而不涉及排序。正如您所看到的,我在我的第一行中提到了第一个问题。 - Ivan Gerasimenko
“我该如何在Oracle中实现Top 1?”除了被接受的答案外,所有其他答案都展示了如何对结果集进行排序并获取第一个有序结果。“Oracle选择前10条记录”中,OP明确询问为什么他们得到的是随机行而不是顶部有序行。它们是重复的。 - MT0
顺便提一下,我无法删除这个问题,因为系统禁止这样做:有些人已经回答了它。 - Ivan Gerasimenko
这个有最佳答案。 - Jim
4个回答

51
... where rownum = 1 order by trans_date desc

这个语句任选一条记录 (where rownum = 1),然后对这个记录排序 (order by trans_date desc)。

正如Ivan所示,您可以使用子查询,在其中对记录进行排序,并在外部查询中保留第一条记录 where rownum = 1。然而,这种方法极其针对Oracle,违反了SQL标准,即子查询结果被视为无序(即DBMS可以忽略 order by 子句)。

因此还是采用标准解决方案。从Oracle 12c开始:

select * 
from table_name 
order by trans_date desc
fetch first 1 row only;

在旧版本中:

select *
from
(
  select t.*, row_number() over (order by trans_date desc) as rn
  from table_name t
)
where rn = 1;

这会返回最小的元素,与 OP 想要的相反。 - user1102532
1
@user1102532:不是的。我按照日期降序排列行,这样就会先显示最近的日期。因此,我保留具有最大日期的行。 - Thorsten Kettner

6

现代Oracle版本有FETCH FIRST

select * from table_name order by trans_date desc
fetch first 1 row only

2

应该使用子查询来使组合 rownum & order 能够工作:

select * from (select * from table_name order by trans_date desc) AS tb where rownum = 1

1
你可以使用窗口函数来实现:
select t.*
from (
  select *, 
         min(trans_date) over () as min_date,
         max(trans_date) over () as max_date
  from the_table 
) t 
where trans_date = min_date 
   or trans_date = max_date;

另一个选择是在派生表上进行连接

select t1.*
from the_table 
  join ( 
    select min(trans_date) over () as min_date,
           max(trans_date) over () as max_date
    from the_table
) t2 on t1.trans_date = t2.min_date 
     or t1.trans_date = t2.max_date;

不确定哪个更快,您需要检查执行计划


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,