繁体   English   中英

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

[英]Oracle sql return rows with different columns values only

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

例如

表A

ID, Fname, Lname, Age 
1   Mike   Smith  10

表B

ID, Fname, Lname, Age  
1   Mike   Smith  20

我的结果应该是

different_columns

Age 
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,使用不同的年龄和lname)

这样做的另一种方法是用大量的案例声明,但是我更喜欢上面的例子,因为如果您的实际表有3个以上的列用于进行此测试,则在更多条件下更容易解决。

如果您不介意每列检查一列(请参阅下一个小提琴),则对于检查那么多列可能更理想。 我不确定是否有更简单的方法。 您必须为每个WHERE子句添加一系列OR,并为每个列比较添加更多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,否则为空)

如果union表和组通过id ,那么你就会知道,任何一组having count(*) > 1至少有1列这是不同的(因为union会自动删除重复项)。

为了确定哪一列是不同的,可以使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM