联合两个select语句,同时保持非空列的不同

时间:2014-03-04 07:36:31

标签: sql oracle oracle11g union

我的Oracle声明分为两部分:

选择语句1将行返回为:

a  b  c  NULL

a  x  y  NULL

Select语句2将行返回为:

a  b  c  d

e  f  g  h

我希望为选择2中具有相同列(NULL列除外)的行提供选择,只返回非NULL行。 输出:

a  b  c  d

a  x  y  NULL

e  f  g  h

更改要求

现在要求有点改变,我的情况如下:

将语句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

即。如果最后一列中有NULL字段,我需要从" Select语句2"中获取行。

2 个答案:

答案 0 :(得分:0)

考虑到前三列不可为空,您可以使用FULL OUTER JOIN

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 :(得分:0)

假设我们得到TABLE1TABLE2,在此查询中TAB1返回表中的相同行并从该行中删除空列,TAB2返回所有行TABLE1TABLE2TAB3中的行相同的行是TAB2,但表格已更改,最后UNION ALL 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;

SQL Fiddle1

SQL Fiddle2