我的问题比下面帖子中的问题更进一步: 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
那将返回该行的状态。但是就像在两个不同示例中提到的那样,有时必须将更多列分组才能确定有效日期。
有人可以帮我编写该功能吗?
答案 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;