【问题标题】:Oracle - inner and left joinOracle - 内连接和左连接
【发布时间】:2018-07-31 18:15:26
【问题描述】:
create table t1 (v varchar2(500), n number);
Insert into T1 (V,N) values ('a',1);
Insert into T1 (V,N) values ('bb',2);
Insert into T1 (V,N) values ('c',3);
Insert into T1 (V,N) values ('d',4);

create table t2 (v varchar2(500), n number);
Insert into T2 (V,N) values ('a',1);
Insert into T2 (V,N) values ('bb',2);

select * from t1 join t2 on t1.v = t2.v 
union all
select * from t1 LEFT join t2 on t1.v = t2.v ;

输出:

    a     1     a         1
    bb    2     bb        2
    a     1     a         1
    bb    2     bb        2
    d     4     (null)  (null)
    c     3     (null)  (null)

我们能否从 T1 和 T2 的单次扫描(即从没有 UNION ALL 等的单次查询)获得相同的上述输出?想要重写上面的 Select 查询,以便它只扫描表 T1 和 T2 一次并给出相同的结果。请参阅左连接。


由于我们在应用程序中进一步传递输出,因此无法更改输出,根据要求需要重复数据。

【问题讨论】:

  • 为什么要前两行两次?您是否正在寻找full outer joinrextester.com/RMEY58806
  • 奇怪的预期结果。
  • 加载一次是什么意思?你的意思是在查询中只使用一次?

标签: sql oracle join outer-join


【解决方案1】:

"想要重写上面的 Select 查询,使其只扫描 T1 和 T2 表一次"

您可以使用子查询分解。 WITH 子句读取每个表一次,UNION-ed 查询从它们读取:

with cte1 as ( select * from t1 )
   , cte2 as ( select * from t2 ) 
select * from cte1 join cte2 on cte1.v = cte2.v 
union all
select * from cte1 LEFT join cte2 on cte1.v = cte2.v ;

这里是a SQL Fiddle demo

【讨论】:

  • 输出无法更改,因为我们在应用程序中进一步传递它,根据要求需要重复数据。感谢@a_horse_with_no_name 和 APC。 With 子句会有所帮助。
【解决方案2】:

您可以通过将行加倍来避免过多的联接和联合:

select t1.*,t2.* from t1
  left join t2 on t1.v=t2.v
  cross join (select 1 as dbl from dual 
            union select 2 as dbl from dual) dbl
where dbl=1 or t2.v is not null

【讨论】:

    猜你喜欢
    • 2016-10-02
    • 1970-01-01
    • 2017-08-15
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多