显示两个不同表中两列之间的差异(比较表)

时间:2015-02-06 16:03:39

标签: sql oracle

我有两张表具有相同的结构和几乎相同的内容。主要区别在于一个值列可能与第二个表中的“等效”列不同。最重要的是,一个记录可能出现在一个表中,但不会出现在另一个表中。

我的桌子:

表1(idA,valueA,valueB,valueC(可空),valueX)
表2(idB,valueA,valueB,valueC(可空),valueY)

期望的结果:

表3(valueA,valueB,valueC,valueX,valueY)

前提条件:

  • 'id'是主键,可以在两个表中有所不同
  • 'valueC'是唯一可以具有 null 值的列。但是,两个表中的值都相同。
  • 如果记录显示在表1中但不在表2中,则'valueY'应为 null
  • 如果记录显示在表2中但不在表1中,则'valueX'应为 null

示例:

表1
1 | 1001 | 2001 | 3001 | 100.0
2 | 1002 | 2002 | 3002 | 95.0
3 | 1003 | 2003年| (null)| 113.0
4 | 1004 | 2004年| 3004 | 75.0

表2
23 | 1001 | 2001 | 3001 | 100.0
24 | 1002 | 2002 | 3002 | 94.0
25 | 1003 | 2003年| (null)| 116.0
26 | 1005 | 2005年| 3005 | 32.0

期望的结果应该是:

表3
1001 | 2001 | 3001 | 100.0 | 100.0
1002 | 2002 | 3002 | 95.0 | 94.0
1003 | 2003年| (null)| 113.0 | 116.0
1004 | 2004年| 3004 | 75.0 | (null)
1005 | 2005年| 3005 | (null)| 32.0

我认为我已经提出了一个解决方案,但速度极慢,我不确定这是否是最简单的方法。

SELECT valueA, valueB, valueC, valueX, valueY
FROM (
    (SELECT t1.valueA, t1.valueB, t1.valueC, t1.valueX, t2.valueY
    FROM Table1 t1
    LEFT JOIN Table2 t2
        ON t1.valueA = t2.valueA 
        AND t1.valueB = t2.valueB 
    WHERE t1.valueC = t2.valueC OR t1.valueC IS NULL OR t2.valueC IS NULL)
    UNION
    (SELECT t2.valueA, t2.valueB, t2.valueC, t1.valueX, t2.valueY
    FROM Table2 t2
    LEFT JOIN Table1 t1
        ON t1.valueA = t2.valueA 
        AND t1.valueB = t2.valueB 
    WHERE t1.valueC = t2.valueC OR t1.valueC IS NULL OR t2.valueC IS NULL)
    );

我希望有人能想出更优雅的解决方案。作为旁注,我使用的是Oracle DB。提前感谢您的时间和帮助!

2 个答案:

答案 0 :(得分:0)

创建表c as(从表中选择* a从表B中选择减号*)联合(从表b中选择*减去表A中的选择*)

答案 1 :(得分:0)

此查询提供所需的输出。我不知道它是否更优雅,但肯定会更短; - )

select valueA, valueB, nvl(table1.valueC, table2.valueC) valueC, valueX, valueY 
  from table1
    full join table2 using (valueA, valueB)
  order by valueA

BTW您的查询只提供了4行,没有1004 | 2004 | 3004 | 75.0 | (null),可能您的where应该是:

where t1.valueC = t2.valueC OR t1.valueC IS NULL or t2.valueC IS NULL

而不是

WHERE t1.valueC = t2.valueC OR (t1.valueC IS NULL AND t1.valueC IS NULL)

重新设计的查询

select a, b, nvl(t1c, t2c) c, x, y
  from (
    select nvl(t1.valueA, t2.valueA) a, nvl(t1.valueB, t2.valueB) b, 
        t1.valueC t1c, t2.valueC t2c, valueX x, valueY y
      from table1 t1 
        full join table2 t2 on (t1.valueA = t2.valueA and t1.valueB = t2.valueB
          and ( t1.valueC = t2.valueC or (t1.valueC is null and t2.valueC is null) ) )
        )
  order by a, b, c