Sql 合并两个select语句,同时保持NOTNULL列的distinct

Sql 合并两个select语句,同时保持NOTNULL列的distinct,sql,oracle,oracle11g,union,Sql,Oracle,Oracle11g,Union,我的Oracle声明包括两部分: Select语句1返回的行为: a b c NULL a x y NULL a b c d e f g h Select语句2返回的行为: a b c NULL a x y NULL a b c d e f g h 我想将为具有与select 2中相同列(NULL列除外)的行提供的两个select合并,只返回not NULL行。 输出: 更改的要求: with t1(c1, c2, c3, c4,

我的Oracle声明包括两部分:

Select语句1返回的行为:

a  b  c  NULL

a  x  y  NULL
a  b  c  d

e  f  g  h
Select语句2返回的行为:

a  b  c  NULL

a  x  y  NULL
a  b  c  d

e  f  g  h
我想将为具有与select 2中相同列(NULL列除外)的行提供的两个select合并,只返回not NULL行。 输出:

更改的要求

with t1(c1, c2, c3, c4, c5) as (
select 'a', 'b', 'c', 'e', null from dual
union all
select 'a', 'x', 'y', 's', null from dual),
t2(c1, c2, c3, c4, c5) as (
select 'a', 'b', 'c', 'd', 'qwerty' from dual
union all
select 'e', 'f', 'g', 'h', 'asdfgh' from dual)
select c1,
       c2,
       c3,
       nvl(nvl2(t1.c5, t1.c4, t2.c4), t1.c4) c4,
       coalesce(t1.c5, t2.c5) c5
  from t1
  full outer join t2
 using (c1, c2, c3);

C1 C2 C3 C4 C5
-- -- -- -- ------
a  b  c  d  qwerty
e  f  g  h  asdfgh
a  x  y  s  (NULL)
要求现在有点变化,我的案例如下:

选择语句1作为:

a b c e NULL

a x y s NULL
选择语句2作为:

a b c d text

e f g h text
输出:

a b c d text

a x y s NULL

e f g h text

也就是说,如果最后一列中的字段为空,我需要从“Select语句2”中获取行。

考虑到前三列不可为空,您可以使用
完全外部联接

with t1 as (
select 'a' c1, 'b' c2, 'c' c3, null c4 from dual
union all
select 'a', 'x', 'y', null from dual),
t2 as (
select 'a' c1, 'b' c2, 'c' c3, 'd' c4 from dual
union all
select 'e', 'f', 'g', 'h' from dual)
 select c1, c2, c3, coalesce(t1.c4, t2.c4) c4 
  from t1 full outer join t2 using(c1, c2, c3);

C1 C2 C3 C4
-- -- -- --
a  b  c  d
e  f  g  h
a  x  y (NULL)
根据更新的要求

with t1(c1, c2, c3, c4, c5) as (
select 'a', 'b', 'c', 'e', null from dual
union all
select 'a', 'x', 'y', 's', null from dual),
t2(c1, c2, c3, c4, c5) as (
select 'a', 'b', 'c', 'd', 'qwerty' from dual
union all
select 'e', 'f', 'g', 'h', 'asdfgh' from dual)
select c1,
       c2,
       c3,
       nvl(nvl2(t1.c5, t1.c4, t2.c4), t1.c4) c4,
       coalesce(t1.c5, t2.c5) c5
  from t1
  full outer join t2
 using (c1, c2, c3);

C1 C2 C3 C4 C5
-- -- -- -- ------
a  b  c  d  qwerty
e  f  g  h  asdfgh
a  x  y  s  (NULL)

这是一个又快又脏的黑客。尽管它适用于您提供的示例数据,但在您的完整数据集中,它的行为可能不可预测。这只是给你一个如何实现目标的想法。我强烈建议您在使用前彻底测试。

假设我们得到了
表1
表2
,在该查询中,
TAB1
返回表中相同的行,并从该行中删除空列,
TAB2
返回
TAB1
中的所有行,不包括与
TAB2
中的行相同的行,
TAB3
相同
TAB2
但表已更改,最后合并所有TAB1、TAB2和TAB3:

SELECT * FROM
(SELECT 
CASE WHEN T1.COL1 IS NULL THEN T2.COL1 ELSE T1.COL1 END COL1,
CASE WHEN T1.COL2 IS NULL THEN T2.COL2 ELSE T1.COL2 END COL2,
CASE WHEN T1.COL3 IS NULL THEN T2.COL3 ELSE T1.COL3 END COL3,
CASE WHEN T1.COL4 IS NULL THEN T2.COL4 ELSE T1.COL4 END COL4
FROM 
TABLE2 T2 INNER JOIN TABLE1 T1 ON 
(T1.COL1 = T2.COL1 OR T1.COL1 IS NULL OR T2.COL1 IS NULL) AND 
(T1.COL2 = T2.COL2 OR T1.COL2 IS NULL OR T2.COL2 IS NULL) AND 
(T1.COL3 = T2.COL3 OR T1.COL3 IS NULL OR T2.COL3 IS NULL) AND 
(T1.COL4 = T2.COL4 OR T1.COL4 IS NULL OR T2.COL4 IS NULL))TAB1
UNION ALL
SELECT * FROM
(SELECT * FROM TABLE1
MINUS
SELECT T1.*
FROM 
TABLE2 T2 INNER JOIN TABLE1 T1 ON 
(T1.COL1 = T2.COL1 OR T1.COL1 IS NULL OR T2.COL1 IS NULL) AND 
(T1.COL2 = T2.COL2 OR T1.COL2 IS NULL OR T2.COL2 IS NULL) AND 
(T1.COL3 = T2.COL3 OR T1.COL3 IS NULL OR T2.COL3 IS NULL) AND 
(T1.COL4 = T2.COL4 OR T1.COL4 IS NULL OR T2.COL4 IS NULL))TAB2
UNION ALL
SELECT * FROM
(SELECT * FROM TABLE2
MINUS
SELECT T2.*
FROM 
TABLE2 T2 INNER JOIN TABLE1 T1 ON 
(T1.COL1 = T2.COL1 OR T1.COL1 IS NULL OR T2.COL1 IS NULL) AND 
(T1.COL2 = T2.COL2 OR T1.COL2 IS NULL OR T2.COL2 IS NULL) AND 
(T1.COL3 = T2.COL3 OR T1.COL3 IS NULL OR T2.COL3 IS NULL) AND 
(T1.COL4 = T2.COL4 OR T1.COL4 IS NULL OR T2.COL4 IS NULL))TAB3;

那么您希望得到什么结果呢?感谢Yaroslav的解决方案,但是在我的例子中,我得到的所有行都有null和notnull字段。我想它并没有选择t1.c4作为null。请评论