Sql 在Oracle数据库中逐列比较两行

Sql 在Oracle数据库中逐列比较两行,sql,oracle11g,Sql,Oracle11g,我需要编写一个查询来逐列比较,即:查找数据库中两行之间的差异。例如: row1: 10 40 sometext 24 row2: 10 25 sometext 24 执行查询后,它应该只显示有差异的字段,即:第二个字段 以下是我迄今为止所做的工作: select table1.column1, table1.column2, table1.column3, table1.column4 from table1 where somefield in (field1, field2); 上面

我需要编写一个查询来逐列比较,即:查找数据库中两行之间的差异。例如:

row1: 10 40 sometext 24
row2: 10 25 sometext 24
执行查询后,它应该只显示有差异的字段,即:第二个字段

以下是我迄今为止所做的工作:

select table1.column1, table1.column2, table1.column3, table1.column4 
from table1 
where somefield in (field1, field2);
上面的查询将显示两行,一行在另一行之上,如下所示: 10 40一些文字24 10 25一些文字24

然后我必须手动进行比较,这需要花费很多时间b/c行包含很多列。 所以我的问题是:如何编写一个只显示有差异的列的查询


感谢使用UNPIVOT子句see将列转换为行,然后通过使用COUNT使用GROUP筛选出相同的行,最后使用PIVOT仅获取具有不同列的行。

要轻松完成此操作,您需要查询表的元数据以获取每一行。您可以将以下代码用作脚本

用表名替换define table_name,并定义yes\u drop\u it=NO。将原始WHERE语法放入WHERE\u子句中。比较逻辑总是比较where子句返回的前两行

whenever sqlerror exit failure rollback;

set linesize 150

define test_tab_name = tst_cf_cols
define yes_drop_it = YES
define order_by = 1, 2
define where_clause = 1 = 1
define tab_owner = user

<<clearfirst>> begin
  for clearout in (
    select 'drop table ' || table_name as cmd
    from all_tables 
    where owner = &&tab_owner and table_name = upper('&&test_tab_name')
    and '&&yes_drop_it' = 'YES'
  ) loop
    execute immediate clearout.cmd;
    execute immediate '
        create table &&test_tab_name as
        select 10 as column1, 40 as column2, ''sometext'' as column3, 24 as column4 from dual
        union all
        select 10 as column1, 25 as column2, ''sometext'' as column3, 24 as column4 from dual
    ';
  end loop;
end;
/

column cfsynt format a4000 word_wrap new_value comparison_syntax

with parms as (select 'parmquery' as cte_name, 'row_a' as corr_name_1, 'row_b' as corr_name_2 from dual)
select 
  'select * from (select ' || LISTAGG(cfcol || ' AS cf_' || trim (to_char (column_id, '000')) || '_' || column_name 
, chr(13) || ', ') WITHIN GROUP (order by column_id) 
  || chr(13) || ' from (select * from parmquery where row_number = 1) ' || corr_name_1 
  || chr(13) || ',  (select * from parmquery where row_number = 2) ' || corr_name_2
  || chr(13) || ') where ''DIFFERENT'' IN (' || LISTAGG ('cf_' || trim (to_char (column_id, '000')) || '_' || column_name, chr(13) || ', ') within group (order by column_id) || ')' 
  as cfsynt
from parms, (
  select 
    'decode (' || corr_name_1 || '.' || column_name || ', ' || corr_name_2
    || '.' || column_name || ', ''SAME'', ''DIFFERENT'')'  
    as cfcol,
    column_name,
    column_id
  from 
    parms, 
    all_tab_columns
  where
    owner = &&tab_owner and table_name = upper ('&&test_tab_name')
);

with parmquery as (select rownum as row_number, vals.* from (
  select * from &&test_tab_name 
  where &&where_clause
  order by &&order_by
  ) vals 
) &&comparison_syntax
;