Oracle SQL联合表1和表2,如果表2包含更多内容,则结果为空

Oracle SQL联合表1和表2,如果表2包含更多内容,则结果为空,sql,oracle,join,left-join,union,Sql,Oracle,Join,Left Join,Union,我将试着用一个例子来解释 我有两张桌子: table1 column1 column2 column3 000001 ABC COD1 000001 ABC COD2 000002 BCD COD3 000003 EDF COD1 000003 EDF COD3 000004 FGH COD1 000004 FGH COD2 000004 FGH COD3 000004 FGH COD4

我将试着用一个例子来解释

我有两张桌子:

table1
column1 column2 column3
000001   ABC     COD1
000001   ABC     COD2
000002   BCD     COD3
000003   EDF     COD1
000003   EDF     COD3
000004   FGH     COD1
000004   FGH     COD2
000004   FGH     COD3
000004   FGH     COD4

table2
column3
COD1
COD2
COD3
COD4
COD5
COD6
COD7
表2仅包含表1第3列的所有可能代码(仅此)。 表1包含了我的真实数据。 我不想要表2第5部分第6部分和第7部分

我必须得到这样的结果

000001   ABC     COD1
000001   ABC     COD2
null     null    COD3
null     null    COD4
null     null    COD1
null     null    COD2
000002   BCD     COD3
null     null    COD4
000003   EDF     COD1
null     null    COD2
000003   EDF     COD3
null     null    COD4
000004   FGH     COD1
000004   FGH     COD2
000004   FGH     COD3
000004   FGH     COD4
我需要用oracle SQL来实现这一点,但我不确定这是否可行。如果需要,我可以接受第一列始终是我当前的column1(即使column2为null)。我不希望重复,例如两个000004 FGH COD4,但如果为空,我希望重复

我尝试了我所知道的一切。。。但我能做的最好的事情是在子查询上使用减号或右连接的并集,其中我需要指定column1条件

编辑这是一位朋友在我尝试时找到的正确答案

select * from
(select distinct a.col1, a.col2
from table1 a
right join (select col3 from table2 f
 where f.col3 IN ('COD1','COD3','COD6')) b
on a.col3 = b.col3),
(select col3 from table2 f
 where f.col3 IN ('COD1','COD3','COD6'));

您可以使用
交叉连接
生成行,然后使用
左连接

select t1.col1, t1.col2, c3.col3
from (select distinct col1 from table1) c1 cross join
     table2 c3 left join
     table1 t1
     on t1.col1 = c1.col1 and t1.col3 = c3.col3
order by c1.col1, c3.col3;

注意:前两列中有
NULL
值似乎很奇怪。这会产生完全重复的行。如果使用
选择c1.col1、t1.col2、c3.col3
,则第一列中会有有效值。

您可以使用
交叉连接
生成行,然后
左连接

select t1.col1, t1.col2, c3.col3
from (select distinct col1 from table1) c1 cross join
     table2 c3 left join
     table1 t1
     on t1.col1 = c1.col1 and t1.col3 = c3.col3
order by c1.col1, c3.col3;

注意:前两列中有
NULL
值似乎很奇怪。这会产生完全重复的行。如果使用
选择c1.col1、t1.col2、c3.col3
,则第一列中会有有效值。

您需要使用
交叉连接和
左连接,如下所示:

SQL> with table1 (col1,col2,col3) as
  2  (select '000001','ABC','COD1' from dual union all
  3  select '000001','ABC','COD2' from dual union all
  4  select '000002','BCD','COD3' from dual union all
  5  select '000003','EDF','COD1' from dual union all
  6  select '000003','EDF','COD3' from dual ),
  7  TABLE2 (COL3) AS
  8  (SELECT 'COD1' FROM DUAL UNION ALL
  9  SELECT 'COD2' FROM DUAL UNION ALL
 10  SELECT 'COD3' FROM DUAL UNION ALL
 11  SELECT 'COD4' FROM DUAL UNION ALL
 12  SELECT 'COD5' FROM DUAL)
 13  select t11.col1, T11.COL2, T2.COL3
 14  from (SELECT DISTINCT COL1 FROM TABLE1) T1
 15  CROSS JOIN (SELECT * FROM TABLE2 WHERE COL3 IN (SELECT COL3 FROM TABLE1)) T2
 16  LEFT JOIN TABLE1 T11 ON T11.COL1 = T1.COL1 AND T2.COL3 = T11.COL3
 17  ORDER BY T1.COL1, T2.COL3;

COL1   COL COL3
------ --- ----
000001 ABC COD1
000001 ABC COD2
           COD3
           COD1
           COD2
000002 BCD COD3
000003 EDF COD1
           COD2
000003 EDF COD3

9 rows selected.

SQL>

您需要使用
交叉连接
左连接
,如下所示:

SQL> with table1 (col1,col2,col3) as
  2  (select '000001','ABC','COD1' from dual union all
  3  select '000001','ABC','COD2' from dual union all
  4  select '000002','BCD','COD3' from dual union all
  5  select '000003','EDF','COD1' from dual union all
  6  select '000003','EDF','COD3' from dual ),
  7  TABLE2 (COL3) AS
  8  (SELECT 'COD1' FROM DUAL UNION ALL
  9  SELECT 'COD2' FROM DUAL UNION ALL
 10  SELECT 'COD3' FROM DUAL UNION ALL
 11  SELECT 'COD4' FROM DUAL UNION ALL
 12  SELECT 'COD5' FROM DUAL)
 13  select t11.col1, T11.COL2, T2.COL3
 14  from (SELECT DISTINCT COL1 FROM TABLE1) T1
 15  CROSS JOIN (SELECT * FROM TABLE2 WHERE COL3 IN (SELECT COL3 FROM TABLE1)) T2
 16  LEFT JOIN TABLE1 T11 ON T11.COL1 = T1.COL1 AND T2.COL3 = T11.COL3
 17  ORDER BY T1.COL1, T2.COL3;

COL1   COL COL3
------ --- ----
000001 ABC COD1
000001 ABC COD2
           COD3
           COD1
           COD2
000002 BCD COD3
000003 EDF COD1
           COD2
000003 EDF COD3

9 rows selected.

SQL>

下面的查询就可以了

    with t2 as (
    select c3
      from t2
     where c3 in ('COD1', 'COD2', 'COD3', 'COD4')
    )
   ,t3 as (
    select distinct
           c1
          ,c2
      from t1
   )    
  ,t_all as (
   select t3.c1
         ,t3.c2
         ,t2.c3
     from t3
         ,t2 
   )
   select t1.c1
         ,t1.c2
         ,t_all.c3
     from t_all left join t1 on 
          t1.c1 = t_all.c1 and t1.c2 = t_all.c2 and t1.c3 = t_all.c3

下面的查询就可以了

    with t2 as (
    select c3
      from t2
     where c3 in ('COD1', 'COD2', 'COD3', 'COD4')
    )
   ,t3 as (
    select distinct
           c1
          ,c2
      from t1
   )    
  ,t_all as (
   select t3.c1
         ,t3.c2
         ,t2.c3
     from t3
         ,t2 
   )
   select t1.c1
         ,t1.c2
         ,t_all.c3
     from t_all left join t1 on 
          t1.c1 = t_all.c1 and t1.c2 = t_all.c2 and t1.c3 = t_all.c3
您正在寻找从2004年开始的“新”功能,但尚未广泛使用

期望的是,
table 1
包含
column3
中所有值的至少一个值,但是
column2
是稀疏的,必须填充。(注意,您甚至根本不需要
表2

查询很简单,因为在添加列2时,您希望列2为空,因此必须使用
case
语句重置它:

select 
  tab.column1, 
  case when tab.column1 is NOT NULL then tab.column2 end column2, 
  c3.column3
from tab
partition by (column2)
right outer join 
(select distinct column3 from tab) c3
on tab.column3 = c3.column3
order by tab.column2, c3.column3;
这将按要求生成数据:

COLUMN COL COLU
------ --- ----
000001 ABC COD1
000001 ABC COD2
           COD3
           COD4
           COD1
           COD2
000002 BCD COD3
           COD4
000003 EDF COD1
           COD2
000003 EDF COD3
           COD4
000004 FGH COD1
000004 FGH COD2
000004 FGH COD3
000004 FGH COD4
请注意,manuall解决方案(即在分区外部联接之前)是从
表1
中获取列2和列3的所有组合-请参见下面的子查询
comb

在第二步中,简单地将
外部联接
连接到您的表

with col2 as(
select distinct column2 from tab),
col3 as (
select distinct column3 from tab),
comb as (
select *
from col2 cross join col3)
select tab.column1, tab.column2, comb.column3 from comb
left outer join tab 
on comb.column2 = tab.column2 and comb.column3 = tab.column3
order by comb.column2, comb.column3
;
这会得到同样的结果。

您正在寻找一个2004年推出的“新”功能,但尚未广泛使用

期望的是,
table 1
包含
column3
中所有值的至少一个值,但是
column2
是稀疏的,必须填充。(注意,您甚至根本不需要
表2

查询很简单,因为在添加列2时,您希望列2为空,因此必须使用
case
语句重置它:

select 
  tab.column1, 
  case when tab.column1 is NOT NULL then tab.column2 end column2, 
  c3.column3
from tab
partition by (column2)
right outer join 
(select distinct column3 from tab) c3
on tab.column3 = c3.column3
order by tab.column2, c3.column3;
这将按要求生成数据:

COLUMN COL COLU
------ --- ----
000001 ABC COD1
000001 ABC COD2
           COD3
           COD4
           COD1
           COD2
000002 BCD COD3
           COD4
000003 EDF COD1
           COD2
000003 EDF COD3
           COD4
000004 FGH COD1
000004 FGH COD2
000004 FGH COD3
000004 FGH COD4
请注意,manuall解决方案(即在分区外部联接之前)是从
表1
中获取列2和列3的所有组合-请参见下面的子查询
comb

在第二步中,简单地将
外部联接
连接到您的表

with col2 as(
select distinct column2 from tab),
col3 as (
select distinct column3 from tab),
comb as (
select *
from col2 cross join col3)
select tab.column1, tab.column2, comb.column3 from comb
left outer join tab 
on comb.column2 = tab.column2 and comb.column3 = tab.column3
order by comb.column2, comb.column3
;


这会得到同样的结果。

好的,我忘记了两件事。1.我不想要复制品。2.我只想要几张第二张桌子,我知道这很奇怪,但如果可能的话,我需要这样的东西。基本上,我需要一遍又一遍地重复第二个表的一些值,并且只显示表一的结果,如果该表得到了代码中的任何结果。1.我不想要复制品。2.我只想要几张第二张桌子,我知道这很奇怪,但如果可能的话,我需要这样的东西。基本上,我需要一遍又一遍地重复第二个表的一些值,并且只有在该表得到该代码的任何结果时才显示该表的结果。我编辑了我的问题,因为我忘记了我需要的一些东西。我现在从您的查询中得到一个错误“缺少关键字”我可以使用此代码,但仍然不是我所需要的。在表1中用3个不同的col1更新了代码,请参见此我编辑了我的问题,因为我忘记了一些我需要的东西。我从您的查询中得到一个错误,现在“缺少关键字”我可以使用此代码,但仍然不是我所需要的。在表1中用3个不同的col1更新了代码,看到这个了吗?我如何使用。我得到了“recursive WITH子句必须有列别名列表”确定我找到了如何使用它。我马上检查一下是否正确。谢谢你这不对。每列1-3都有多个条目couple@LiefLayer已更新查询。我用你的数据进行了测试,它现在生成了你期望的准确结果。我如何使用。我得到了“recursive WITH子句必须有列别名列表”确定我找到了如何使用它。我马上检查一下是否正确。谢谢你这不对。每列1-3都有多个条目couple@LiefLayer已更新查询。我用你的数据进行了测试,它产生了你现在期望的准确结果。