如下所示;我如何实现fx.ftf_validitystartdate = ...这个行值,因为oracle不允许我这样做,如下所示
select * from acc_accounts acc
join kp_paramcore p on
acc.account_no = p.accountnum
acc.suffix = p.suffixc
LEFT JOIN ftf_rates fx
ON p.maturestart = fx.ftf_vadealtsinir
AND p.maturefinish = fx.ftf_vadeustsinir
AND fx.statusrec = 'A'
AND fx.currencycode = acc.currencsw_kod
AND fx.status= 'A'
and fx.ftf_validitystartdate= (SELECT MAX(ff.ftf_validitystartdate)
FROM ftf_rates ff
WHERE ff.status = 'A'
AND ff.statusrec = 'A'
AND v_CurrentDate BETWEEN ff.systemstartdate AND ff.systemfinishdate AND ff.currencycode = acc.currencsw_kod
)
答案 0 :(得分:4)
如果将其切换为where
子句,它应该可以工作:
select *
from acc_accounts acc join
kp_paramcore p
on acc.account_no = p.accountnum and
acc.suffix = p.suffixc LEFT JOIN
ftf_rates fx
ON p.maturestart = fx.ftf_vadealtsinir and
p.maturefinish = fx.ftf_vadeustsinir and
fx.statusrec = 'A' and
fx.currencycode = acc.currencsw_kod and
fx.status= 'A'
where fx.ftf_validitystartdate= (SELECT MAX(ff.ftf_validitystartdate)
FROM ftf_rates ff
WHERE ff.status = 'A' and
ff.statusrec = 'A'
p.v_CurrentDate BETWEEN ff.systemstartdate AND ff.systemfinishdate AND ff.currencycode = acc.currencsw_kod
)
但是,您丢失了“左外连接”特征,因此您还需要添加:or fx.ftf_validitystartdate is null
。我猜v_CurrentDate来自“p”。在列名之前使用表别名总是一个好主意。
但是,我怀疑子查询是否真的需要。仅当有多个记录满足子查询中的条件时才需要它。否则,我认为您只需将on
子句更改为:
ON p.maturestart = fx.ftf_vadealtsinir and
p.maturefinish = fx.ftf_vadeustsinir and
fx.statusrec = 'A' and
fx.currencycode = acc.currencsw_kod and
fx.status= 'A'and
p.v_CurrentDate BETWEEN fx.systemstartdate AND fx.systemfinishdate
答案 1 :(得分:4)
我使用CTE发布了解决方法,并仅在Oracle 11g中进行了测试。
To make test I create this schema:
create table t_a ( a int );
create table t_b ( a int);
create table t_c ( a int);
insert into t_a values (1);
insert into t_a values (2);
insert into t_a values (3);
insert into t_b values (1);
insert into t_b values (2);
insert into t_b values (3);
insert into t_c values (1);
insert into t_c values (2);
insert into t_c values (3);
此时我对此查询强制出错:
select *
from t_a
left outer join t_b
on t_a.a = t_b.a and
t_b.a = ( select max( a )
from t_c);
现在我用CTE重写查询:
with cte (a ) as (
select a
from t_b
where t_b.a = ( select min( a )
from t_c)
)
select *
from t_a
left outer join cte
on t_a.a = cte.a;
第二个查询返回正确的结果。
我用CTE重写你的查询:
with CTE as (
select * from ftf_rates
where ftf_validitystartdate= (SELECT MAX(ff.ftf_validitystartdate)
FROM ftf_rates ff
WHERE ff.status = 'A'
AND ff.statusrec = 'A'
AND v_CurrentDate BETWEEN ff.systemstartdate
AND ff.systemfinishdate
AND ff.currencycode = acc.currencsw_kod )
)
select * from acc_accounts acc
join kp_paramcore p on
acc.account_no = p.accountnum
acc.suffix = p.suffixc
LEFT JOIN CTE fx
ON p.maturestart = fx.ftf_vadealtsinir
AND p.maturefinish = fx.ftf_vadeustsinir
AND fx.statusrec = 'A'
AND fx.currencycode = acc.currencsw_kod
AND fx.status= 'A'
注意,仅在Oracle 11g中测试过。参见@a_horse_with_no_name coment:
@danihp:CTE早在Oracle 11g之前就可以使用了(我认为它们是 在9.1中引入甚至可能更早 - 但它们肯定是 可在10.x中获得。 11.2引入了不需要的递归CTE 在这种情况下。 -