Oracle sql仅返回具有不同列值的行

时间:2014-09-05 22:54:25

标签: sql oracle

我有两个表a和表b具有完全相同的结构。我想返回具有不同值的列:有人可以告诉我如何实现以下

例如;

表A

ID, Fname, Lname, Age 
1   Mike   Smith  10

表B

ID, Fname, Lname, Age  
1   Mike   Smith  20

我的结果应该是

different_columns

Age 

2 个答案:

答案 0 :(得分:2)

select id,
       listagg(diff_col, ', ') within group(order by diff_col) as diff_cols
  from (select a.id, 'fname' as diff_col
          from tablea a
          left join tableb b
            on a.id = b.id
           and a.fname = b.fname
         where b.id is null
        union all
        select a.id, 'lname'
          from tablea a
          left join tableb b
            on a.id = b.id
           and a.lname = b.lname
         where b.id is null
        union all
        select a.id, 'age'
          from tablea a
          left join tableb b
            on a.id = b.id
           and a.age = b.age
         where b.id is null)
 group by id

<强>小提琴: http://sqlfiddle.com/#!4/daeaf/4/0

(我添加了一个不同年龄和名字的ID#2,用于说明)

这样做的另一种方法是一个巨大的案例陈述,但我更喜欢上述内容,因为如果您的实际表格中有超过3列用于此测试,则更容易在更多条件下使用。

如果您不介意每列检查一列(请参阅下一个小提琴),这可能更适合检查多列。我不确定有更简单的方法;你必须将一堆OR添加到WHERE子句中,并为每个列比较添加更多case语句。

select a.id,
       case when a.fname <> b.fname then 'X' end as fname,
       case when a.lname <> b.lname then 'X' end as lname,
       case when a.age <> b.age then 'X' end as age
  from tablea a
  join tableb b
    on a.id = b.id
 where a.fname <> b.fname
    or a.lname <> b.lname
    or a.age <> b.age

<强>小提琴: http://sqlfiddle.com/#!4/daeaf/7/0

(如果指示的列有差异,则显示X,否则没有)

答案 1 :(得分:0)

如果union id表格和having count(*) > 1分组,则您知道任何群组union至少有一列不同(从{到{ {1}}自动删除重复项。)

为了确定哪个列不同,您可以使用count(distinct column_name)查看哪些列具有多个不同的值。

select id,
    count(distinct fname) fname,
    count(distinct lname) lname,
    count(distinct age) age
from (
    select * from tablea
    union
    select * from tableb
) t1 group by id
having count(*) > 1