Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
联接问题:更正SQL语句以解决:ORA-01799:列不能外部联接到子查询_Sql_Oracle_Join_Left Join - Fatal编程技术网

联接问题:更正SQL语句以解决:ORA-01799:列不能外部联接到子查询

联接问题:更正SQL语句以解决:ORA-01799:列不能外部联接到子查询,sql,oracle,join,left-join,Sql,Oracle,Join,Left Join,正如你在下面看到的;如何实现fx.ftf_validitystardate=。。。因为oracle不允许我像下面这样做,所以这行代码很有价值 如果您将其切换到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.ftf_validitystardate=。。。因为oracle不允许我像下面这样做,所以这行代码很有价值


如果您将其切换到
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
                                )
但是,您将丢失“左外部联接”特征,因此您还需要添加:
或fx.ftf_validitystardate为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

如果您将其切换到
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
                                )
但是,您将丢失“左外部联接”特征,因此您还需要添加:
或fx.ftf_validitystardate为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

我使用CTE发布了解决方案,并仅在Oracle 11g中进行了测试

:

此时,我强制此查询出错:

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;
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' 
第二个查询返回正确的结果

我用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;
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中进行了测试。请参见“一匹没有名字的马”:


@danihp:CTE早在Oracle 11g之前就已经可用了(我想是的) 在9.1中引入可能更早,但它们肯定是 10.x版提供)。11.2引入了不需要的递归CTE 在这种情况下——


我使用CTE发布了解决方案,并仅在Oracle 11g中进行了测试

:

此时,我强制此查询出错:

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;
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' 
第二个查询返回正确的结果

我用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;
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中进行了测试。请参见“一匹没有名字的马”:


@danihp:CTE早在Oracle 11g之前就已经可用了(我想是的) 在9.1中引入可能更早,但它们肯定是 10.x版提供)。11.2引入了不需要的递归CTE 在这种情况下——


复制粘贴查询中的
fx.status='A'
之后丢失?oracle 10g版,并且必须在11gI上也工作假定您在
上以及在
kp\u paramcore
加入?@danihp:CTE早在oracle 11g之前就可用了(我认为它们是在9.1中引入的,可能更早——但它们肯定在10.x中可用).11.2引入了本例中不需要的递归CTE。@一个没有名字的马,请查看我的答案。谢谢更正我的评论。
在您的复制粘贴查询中
fx之后缺失。status='a'
?oracle版本10g,并且必须在11gI上工作,假设您在
kp参数之后也在
上缺失了
re
join?@danihp:CTE早在Oracle 11g之前就已经推出了(我认为它们可能在9.1中引入,甚至更早,但它们在10.x中肯定是可用的)。11.2引入了递归CTE,在这种情况下不需要它。@a_horse_,没有名字,请查看我的答案。谢谢纠正我的评论。