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已更新查询。我用你的数据进行了测试,它产生了你现在期望的准确结果。