如何编写函数以获取oracle中一行的当前生效日期

时间:2018-10-27 11:39:11

标签: sql oracle

我的问题比下面帖子中的问题更进一步: How to get the current effective date in Oracle?

我有一些表格,例如帖子中的示例:

TID  TName  EffectiveDate   
   1    A      2011-7-1    
   2    A      2011-8-1    
   3    A      2011-9-1
   4    A      2011-10-1    
   5    B      2011-8-1    
   6    B      2011-9-1    
   7    B      2011-10-1    
   8    C      2011-9-1    
   etc...

如果今天是2011-9-10,我希望查询结果是这样的:

TID  TName  EffectiveDate  Status    
   1    A      2011-7-1      Invalid    
   2    A      2011-8-1      Invalid    
   3    A      2011-9-1      Valid    
   4    A      2011-10-1     Inactive    
   5    B      2011-8-1      Invalid    
   6    B      2011-9-1      Valid    
   7    B      2011-10-1     Inactive
   8    C      2011-9-1      Valid

在上面的问题中,有一个这样的解决方案:

select TID,
       TName,
       EffectiveDate,
       decode(sign(EffectiveDate - (select max(T2.EffectiveDate) 
                                    from MyTable T2
                                    where T1.Tname=T2.Tname and 
                                          T2.EffectiveDate <= sysdate)),
              -1,'Invalid',
              0,'Valid',
              'Inactive') Status
from MyTable T1

,效果很好。

我想创建一个函数,您可以使用给定的表作为参数来调用该函数,并以systemdate作为默认日期值返回状态(有效,无效或无效)。

我认为这并不困难。

我的问题是,有时该表包含更多列,您必须将这些列用于确定生效日期。

在上面的示例中,您只需查看TName即可获取当前的有效日期。

在下面的示例中,您必须将emplid和empl_rcd一起使用

TID EMPLID EMPL_RCD EFFECTIVEDATE
1   001    0       2011-07-01
2   001    0       2011-06-25
3   001    1       2011-07-01
4   002    0       2011-07-01
5   002    0       2011-08-01

如果今天是2012年1月1日,则结果必须为:

TID EMPLID EMPL_RCD EFFECTIVEDATE STATUS
1   001    0       2011-07-01  valid
2   001    0       2011-06-25  invalid
3   001    1       2011-07-01  valid
4   002    0       2011-07-01  invalid
5   002    0       2011-08-01  valid

在第二个示例中,我的查询应类似于

select TID,
       TName,
       EffectiveDate,
       decode(sign(EffectiveDate - (select max(T2.EffectiveDate) 
                                    from MyTable T2
                                    where **T1.emplid=T2.emplid and
                                          T1.empl_rcd = T2.empl_rcd and** 
                                          T2.EffectiveDate <= sysdate)),
              -1,'Invalid',
              0,'Valid',
              'Inactive') Status
from MyTable T1

但是我想要一个可以调用的函数,例如

select T1.*,effdt_status(mytable) as status from mytable

那将返回该行的状态。但是就像在两个不同示例中提到的那样,有时必须将更多列分组才能确定有效日期。

有人可以帮我编写该功能吗?

1 个答案:

答案 0 :(得分:0)

这是您要寻找的吗?

select t.*,
       (case sum(case when tdate <= date '2011-09-10' then 1 else 0 end)  over (partition by tname order by tdate desc)
            when 0 then 'Inactive'
            when 1 then 'Valid'
            else 'Invalid'
        end)
from mytable t;

这应将'Inactive'分配给任何将来的日期,将'Valid'分配给最近的日期,并将'Invalid'分配给过去的日期。

您也可以将其表示为:

select t.*,
       (case when tdate > date '2011-09-10' then 'Inactive'
             when not exists (select 1
                              from mytable t2
                              where t2.tname = t.tname and 
                                    t2.tdate > t.tdate and 
                                    t2.tdate <= date '2011-09-10'
                             )
             then 'Valid'
             else 'Invalid'
        end)
from mytable t;