oracle 用于比较两个相同表之间的数据沿着列出每列差异(如果有)的查询

vq8itlhq  于 2023-02-18  发布在  Oracle
关注(0)|答案(2)|浏览(234)

我有两个主键相同的表,每个表都有15列或更多。我需要比较这两个表并列出所有的差异。我们可以为此编写一个通用plsql块或查询吗?
输出应如输出表所示。
表一:
| 主键|第1列|列2|第3栏|col4(n列数)|
| - ------|- ------|- ------|- ------|- ------|
| 1个|一百|四三九|三四五|四百五十六|
| 第二章|二百三十九|二百三十四|五百四十六|小行星5667|
表二:
| 主键|第1列|列2|第3栏|col4(n列数)|
| - ------|- ------|- ------|- ------|- ------|
| 1个|二百|四百五十六|三四五|四百五十九|
| 第二章|二百三十九|二百三十四|小行星5435|小行星4557|
输出表:
| 主键|评论|列名|表1数值|表2数值|
| - ------|- ------|- ------|- ------|- ------|
| 1个|发现不匹配|第1列|一百|二百|
| 1个|发现不匹配|第2列|四三九|四百五十六|
| 1个|发现不匹配|第4列|四百五十六|四百五十九|
| 第二章|发现不匹配|第3列|五百四十六|小行星5435|
| 1个|发现不匹配|第4列|小行星5667|小行星4557|
我尝试了解决方案,这是给我一个标志,在那里有匹配与否。但我不能绕着我的头上如何获得数据,以及,这也是在所需的格式。这是一个面试问题,我需要破解我的理解。

d6kp6zgx

d6kp6zgx1#

无论何时你有问题,请发布一些示例数据(CREATE TABLE和INSERT语句用于所有相关的表,仅相关列),这样想帮助你的人就可以重现问题并测试他们的想法。还可以发布你想要从该数据得到的确切结果,并解释为什么你想要从该数据得到这些结果。最后,不要发布任何图像,因为它们不能被剪切和粘贴。
你可以试试这样的东西。根据你的需要量身定做

create table t1(c1 number(2) primary key, c2 varchar2(10), c3 varchar2(10));

 create table t2(c1 number(2) primary key, c2 varchar2(10), c3 varchar2(10));

 insert into t1 values(1,'a','c');
 insert into t2 values(1,'b','c');
 insert into t1 values(2,'a','b');
 insert into t2 values(2,'a','c');
 insert into t1 values(3,'a','b');
 insert into t2 values(3,'a','b');
 insert into t1 values(4,'a','b');
 insert into t2 values(4,'x','y');
 insert into t1 values(5,'a','b');
 insert into t2 values(6,'a','b');

 select case when t1.c1 is null then 'missing in t1'
                when t2.c1 is null then 'missing in t2'
                    end m1,
               decode( t1.c2, t2.c2, '', 'c2' ) c2_flag,
               decode( t1.c3, t2.c3, '', 'c3' ) c3_flag,
               coalesce(t1.c1,t2.c1) pk,
               t1.c2, t2.c2,
               t1.c3, t2.c3
      from t1 full outer join t2 on (t1.c1 = t2.c1)
    where decode( t1.c2, t2.c2, '', 'c2' ) is not null
       or decode( t1.c3, t2.c3, '', 'c3' ) is not null
    order by pk
 

M1  C2_FLAG C3_FLAG PK  C2  C2  C3  C3
 -  c2   -  1   a   b   c   c
 -   -  c3  2   a   a   b   c
 -  c2  c3  4   a   x   b   y
missing in t2   c2  c3  5   a    -  b    - 
missing in t1   c2  c3  6    -  a    -  b
jq6vz3qz

jq6vz3qz2#

一个选项是使用MODEL clause,它允许您以类似于excel的方式组合来自不同行/列的数据。
下面是代码:

SELECT ID, COMMENTS, COLUMN_NAME, VALUE_1 "TBL_1_VALUE", VALUE_2 "TBL_2_VALUE"
FROM
    (
        Select  *
        From    ( SELECT 'TBL_1' "TABLE_NAME", t1.* FROM tbl_1 t1 UNION ALL
                  SELECT 'TBL_2' "TABLE_NAME", t2.* FROM tbl_2 t2
                )
        MODEL     PARTITION BY (ID)
                  DIMENSION BY (TABLE_NAME)
                  MEASURES (COL1, COL2, COL3, COL4, 
                            'Find a mismatch' "COMMENTS", 
                            'Column mismatched' "COLUMN_NAME",
                            CAST(0 AS Number(6)) "VALUE_1", CAST(0 AS Number(6)) "VALUE_2")
                 RULES ( 
                            COMMENTS['CHK1'] = CASE WHEN  COL1['TBL_1'] != COL1['TBL_2'] THEN  'Mismatch Found' END,
                            COMMENTS['CHK2'] = CASE WHEN  COL2['TBL_1'] != COL2['TBL_2'] THEN  'Mismatch Found' END,
                            COMMENTS['CHK3'] = CASE WHEN  COL3['TBL_1'] != COL3['TBL_2'] THEN  'Mismatch Found' END,
                            COMMENTS['CHK4'] = CASE WHEN  COL4['TBL_1'] != COL4['TBL_2'] THEN  'Mismatch Found' END,
                            --
                            COLUMN_NAME['CHK1'] = CASE WHEN  COL1['TBL_1'] != COL1['TBL_2'] THEN 'COL1' END,
                            COLUMN_NAME['CHK2'] = CASE WHEN  COL2['TBL_1'] != COL2['TBL_2'] THEN 'COL2' END,
                            COLUMN_NAME['CHK3'] = CASE WHEN  COL3['TBL_1'] != COL3['TBL_2'] THEN 'COL3' END,
                            COLUMN_NAME['CHK4'] = CASE WHEN  COL4['TBL_1'] != COL4['TBL_2'] THEN 'COL4' END,
                            --
                            VALUE_1['CHK1'] =  CASE WHEN  COL1['TBL_1'] != COL1['TBL_2'] THEN COL1['TBL_1'] END,
                            VALUE_1['CHK2'] =  CASE WHEN  COL2['TBL_1'] != COL2['TBL_2'] THEN COL2['TBL_1'] END,
                            VALUE_1['CHK3'] =  CASE WHEN  COL3['TBL_1'] != COL3['TBL_2'] THEN COL3['TBL_1'] END,
                            VALUE_1['CHK4'] =  CASE WHEN  COL4['TBL_1'] != COL4['TBL_2'] THEN COL4['TBL_1'] END,
                            --
                            VALUE_2['CHK1'] =  CASE WHEN  COL1['TBL_1'] != COL1['TBL_2'] THEN COL1['TBL_2'] END,
                            VALUE_2['CHK2'] =  CASE WHEN  COL2['TBL_1'] != COL2['TBL_2'] THEN COL2['TBL_2'] END,
                            VALUE_2['CHK3'] =  CASE WHEN  COL3['TBL_1'] != COL3['TBL_2'] THEN COL3['TBL_2'] END,
                            VALUE_2['CHK4'] =  CASE WHEN  COL4['TBL_1'] != COL4['TBL_2'] THEN COL4['TBL_2'] END
                        )
    )
WHERE COMMENTS Is Not Null And SubStr(TABLE_NAME, 1, 3) = 'CHK'
ORDER BY ID, COLUMN_NAME

使用示例数据:

WITH
    tbl_1 (ID,  COL1,   COL2,   COL3,   COL4) AS
        ( Select 1, 100, 439, 345, 456 From Dual Union All 
            Select 2, 239, 234, 546, 5667 From Dual 
        ),
    tbl_2 (ID,  COL1,   COL2,   COL3,   COL4) AS
        ( Select 1, 200, 456, 345, 459 From Dual Union All 
            Select 2, 239, 234, 5435, 4557 From Dual 
        )

.结果应该是:

ID COMMENTS        COLUMN_NAME       TBL_1_VALUE TBL_2_VALUE
---------- --------------- ----------------- ----------- -----------
         1 Mismatch Found  COL1                      100         200 
         1 Mismatch Found  COL2                      439         456 
         1 Mismatch Found  COL4                      456         459 
         2 Mismatch Found  COL3                      546        5435 
         2 Mismatch Found  COL4                     5667        4557

它看起来像很多代码(确实如此),但大部分都可以复制/粘贴,根据我的经验,MODEL子句既快速又可靠...

相关问题