如何将一个 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
基本上,您想逆轴旋转 A
,然后使用 LEFT JOIN
从 b
:
中引入值
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 all
和 cross join
)。
请注意,不需要聚合。而且这个 returns id 按照它们在 A
.
中出现的顺序排列
Here 是一个 db<>fiddle.
我有两个具有不同结构的 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 |
基本上,您想逆轴旋转 A
,然后使用 LEFT JOIN
从 b
:
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 all
和 cross join
)。
请注意,不需要聚合。而且这个 returns id 按照它们在 A
.
Here 是一个 db<>fiddle.