Oracle - 当列可以有空值并且 NULL 是最大日期时查找最大(日期)

Oracle - Finding Max (date) when column could have null values and NULL is the max date

我有一个 table,它的日期列也有日期值和空值。 Null 表示开放日期,因此它是最大日期。 如何使用 sql

找到具有最大日期的行

如果 Null 存在,则该记录是最大日期。如果没有空值,则需要返回具有最大日期的行

一种方法是在子查询中使用像 row_number 这样的分析函数。

像这样:

示例数据

create table t (id number, expiry date);

insert into t (id, expiry) values (3, sysdate);
insert into t (id, expiry) values (8, null);

相关子查询

select id, expiry, row_number() over (order by expiry desc) as rn
from   t;

        ID EXPIRY                          RN
---------- ----------------------- ----------
         8                                  1
         3 01.03.2022 20:27:45              2

请注意 order by ... desc 默认包含选项 nulls first - 所以这正是您需要的。

在外层查询中,只需要select where rn = 1:

select id, expiry
from   (
         select id, expiry, row_number() over (order by expiry desc) as rn
         from   t
       )
where  rn = 1;

        ID EXPIRY                 
---------- -----------------------
         8                        

我要求对“关系”进行澄清。如果它们在您的数据中是可能的,您必须阐明所需的处理方式。例如,如果您必须 return 所有具有“最新日期”的行,那么您应该使用 rank() 而不是 row_number()。例如:

在 table

中再添加一行
insert into t (id, expiry) values (9, null);

修改后的查询:

select id, expiry
from   (
         select id, expiry, rank() over (order by expiry desc) as rn
         from   t
       )
where  rn = 1;

        ID EXPIRY                 
---------- -----------------------
         8                        
         9   

请注意,Oracle 优化器在此类查询中非常智能 - 事实上,它不会按日期对所有行执行完整排序。该计划将包括一个 window sort pushed rank 操作,该操作仅完成查找排名(或行号)为 1 的行所需的最少工作;它没有按排序列完全排序所有行(在我的示例中为 expiry)。