简体   繁体   English

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

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

I have two tables table a and table b with exact same structure. 我有两个表a和表b的结构完全相同。 I would like to return the columns with different values: Could somebody tell me how to achieve the below 我想返回具有不同值的列:有人可以告诉我如何实现以下目标

for eg; 例如

Table A 表A

ID, Fname, Lname, Age 
1   Mike   Smith  10

Table B 表B

ID, Fname, Lname, Age  
1   Mike   Smith  20

My result should be 我的结果应该是

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

Fiddle: http://sqlfiddle.com/#!4/daeaf/4/0 小提琴: http ://sqlfiddle.com/#!4/daeaf/4/0

(I added an ID # 2 with a different age AND lname, for illustration) (为说明起见,我添加了一个ID#2,使用不同的年龄和lname)

Another way of doing this is a giant case statement but I would prefer the above as it's easier to tack on more conditions should your actual table have more than 3 columns with which you are doing this test. 这样做的另一种方法是用大量的案例声明,但是我更喜欢上面的例子,因为如果您的实际表有3个以上的列用于进行此测试,则在更多条件下更容易解决。

If you don't mind having one column per column check (see next fiddle) this might be more ideal for checking that many columns. 如果您不介意每列检查一列(请参阅下一个小提琴),则对于检查那么多列可能更理想。 I'm not sure there is an easier way; 我不确定是否有更简单的方法。 you'd have to tack on a bunch of ORs to the WHERE clause and a bunch more case statements for each column comparison. 您必须为每个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

Fiddle: http://sqlfiddle.com/#!4/daeaf/7/0 小提琴: http ://sqlfiddle.com/#!4/daeaf/7/0

(this shows an X if there is a difference in the indicated column, otherwise nothing) (如果指示的列中有差异,则显示X,否则为空)

If you union both tables and group by id , then you'll know that any group having count(*) > 1 has at least 1 column that's different (since union automatically removes duplicates). 如果union表和组通过id ,那么你就会知道,任何一组having count(*) > 1至少有1列这是不同的(因为union会自动删除重复项)。

In order to determine which column is different, you can use count(distinct column_name) to see which columns have more than 1 distinct value. 为了确定哪一列是不同的,可以使用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