如何将一个 table 转换为另一个 table 结构并比较数据 |甲骨文

How to convert one table to another table structure and compare data | Oracle

我有两个具有不同结构的 table,但是 TableA 几列与 TableB 不同。 这里我们必须将 TableA 转换为 TableB 结构并比较每个数据并标记 TableB 中缺失的行。如果它在 TableA 中丢失,我需要忽略此类记录。

我不想使用 Union all 并且因为我正在执行批量操作需要考虑查询性能。请建议最好的方法。

TableA

NAME GENDER DEPNAME ID1 ID2 ID3 ID4 ID5
Jacob M Math OfficeID PassPort AppID JobID
Maria F Science LabID OfficeID PassPort AppID

TableB

NAME GENDER DEPNAME ID
Jacob M Math OfficeID
Jacob M Math PassPort
Jacob M Math AppID
Maria F Science LabID
Maria F Science OfficeID
Maria F Science PassPort

Table A-B

Name Gender DepName ID MissingID
Jacob M Math OfficeID No
Jacob M Math PassPort No
Jacob M Math AppID No
Jacob M Math JobID Yes
Maria F Science LabID No
Maria F Science OfficeID No
Maria F Science PassPort No
Maria F Science AppID Yes

您可以对 TableA 的列的所有不同 ID 值使用条件聚合以及非透视行,例如

SELECT a.name AS "Name", a.gender AS "Gender", a.depname AS "Dept Name", a.id, 
       MIN(CASE WHEN a.id != b.id THEN 'Yes' ELSE 'No' END) AS "MissingID"
  FROM
  (
    SELECT DISTINCT *
      FROM TableA a   
   UNPIVOT (id FOR col IN ( id1 AS 'id1',
                            id2 AS 'id2',
                            id3 AS 'id3',
                            id4 AS 'id4',
                            id5 AS 'id5' ))) a
   JOIN TableB b
    ON b.name = a.name
   AND b.gender = a.gender
   AND b.depname = a.depname  
 GROUP BY a.name, a.gender, a.depname, a.id
 ORDER BY a.name, "MissingID"
Name Gender DepName ID MissingID
Jacob M Math OfficeID No
Jacob M Math PassPort No
Jacob M Math AppID No
Jacob M Math JobID Yes
Maria F Science PassPort No
Maria F Science OfficeID No
Maria F Science LabID No
Maria F Science AppID Yes

Demo

基本上,您想逆轴旋转 A,然后使用 LEFT JOINb:

中引入值
SELECT a.*,
       (CASE WHEN b.id IS NULL THEN 'Yes' ELSE 'No' END) as is_missing
FROM (SELECT a.name, a.gender, a.depname, i.n, i.id
      FROM TableA a CROSS JOIN LATERAL
           (SELECT 1 as n, id1 as id FROM DUAL UNION ALL
            SELECT 2 as n, id2 FROM DUAL UNION ALL
            SELECT 3 as n, id3 FROM DUAL UNION ALL
            SELECT 4 as n, id4 FROM DUAL UNION ALL
            SELECT 5 as n, id5 FROM DUAL
           ) i
      WHERE id IS NOT NULL
     ) a LEFT JOIN
     tableb b
     ON a.name = b.name AND a.gender = b.gender AND a.depname = b.depname AND a.id = b.id
ORDER BY a.name, a.gender, a.depname, a.n;

我更喜欢横向连接来取消旋转。在 Oracle 11 中,您还可以选择 unpivot。但是,更通用的方法确实使用 union all(尽管更快的方法使用 union allcross join)。

请注意,不需要聚合。而且这个 returns id 按照它们在 A.

中出现的顺序排列

Here 是一个 db<>fiddle.