如何仅从两个表中获取不同的列

时间:2019-12-17 11:32:48

标签: sql oracle

我有两个具有相同列的表。我需要比较并仅获取经过修改的列。

ID是主键,可用于比较表A和表B。

表A的原始表和表B的新表将具有相同的修改数据。

Table A
+----+------+---------+---------+-----------+
| ID | Name |  Color  | Country |   City    |
+----+------+---------+---------+-----------+
|  1 | Jim  | Red     | SP      | Barcelona |
|  2 | Hugh | Blue    | PT      | Lisbon    |
|  3 | Marc | Violtet | UK      | London    |
+----+------+---------+---------+-----------+


Table B
+----+--------+---------+---------+------------+
| ID |  Name  |  Color  | Country |    City    |
+----+--------+---------+---------+------------+
|  1 | Jim    | Blue    | SP      | Lisbon     |
|  2 | Roosie | Blue    | PT      | Lisbon     |
|  3 | Marc   | Violtet | UK      | Manchester |
+----+--------+---------+---------+------------+

我该如何查询只给我修改过的数据

示例

ID 1  Old Color Red New color blue.
Id 1   Old City Barcelona New City Lisbon.
...

你能帮我吗?

2 个答案:

答案 0 :(得分:0)

您可以使用union all取消每个表的位置,合并结果并根据更改后的值进行过滤:

select
    a.id,
    a.col,
    a.val old_value,
    b.val new_value
from (
    select 'name' col, id, name val from table_a
    union all select 'color', id, color from table_a
    union all select 'country', id, country from table_a
    union all select 'city', id, city from table_a
) a
inner join (
    select 'name' col, id, name val from table_b
    union all select 'color', id, color from table_b
    union all select 'country', id, country from table_b
    union all select 'city', id, city from table_b
) b
    on a.id = b.id and a.col = b.col and a.val <> b.val
order by a.id, a.col

我没有生成描述差异的文本,因为我发现理解和操作列最方便,但是您可以通过字符串串联轻松地实现。

Demo on DB Fiddle

ID | COL   | OLD_VALUE | NEW_VALUE 
-: | :---- | :-------- | :---------
 1 | city  | Barcelona | Lisbon    
 1 | color | Red       | Blue      
 2 | name  | Hugh      | Roosie    
 3 | city  | London    | Manchester

答案 1 :(得分:0)

您可以这样做:

select a.id, case when a.color!=b.color then 'old color '||a.color||' new color '||b.color end as color_change, .... same for all columns you want
from tablea a join tableb b on (a.id=b.id)
where a.color!=b.color or a.city!=b.city ... 

这将给您每个ID一行。如果您希望每行(id,attribute)行,则性能最佳的SQL取决于表的大小以及增量(即有多少行是不同的)。您可以尝试以下方法:

with delta as (select a.id, a.color, a.name, a.city, ..., b.name as bname, b.color as bcolor, ...
from tablea a join tableb b on (a.id=b.id)
where a.color!=b.color or a.city!=b.city ...)
select id, 'Old Color '||color||' new color '||bcolor
from delta where color!=bcolor
union all
select id, 'Old City '||city||' new city '||bcity
from delta where city!=bcity
union all
 .....