1

以下に示すように; fx.ftf_validitystartdate =を実装するにはどうすればよいですか...この行の値は、オラクルでは以下のように実行することを許可していないためです。

    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
    )
4

2 に答える 2

5

これを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
于 2012-12-17T14:39:38.030 に答える
4

CTEを使用して回避策を公開し、Oracle11gでのみテストしました。

テストを行うために、次のスキーマを作成します

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;

この2番目のクエリは正しい結果を返します。

私はあなたのクエリを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' 

Oracle11gでのみテストされていることに注意してください。@a_horse_with_no_nameコメントを参照してください:

@danihp:CTEはOracle 11gよりずっと前に利用可能でした(9.1で導入されたのはおそらくもっと早いと思いますが、10.xでは間違いなく利用可能です)。11.2では、この場合は不要な再帰CTEが導入されました。– </ p>

于 2012-12-17T20:34:57.570 に答える