比较两个表中的大量数据以查找缺失数据

Comparing lots of data from two tables to find missing data

我有两个 table 需要比较并查找缺少数据的条目。

示例:

order_table                             rtm_table
----------------------------            ---------------------------------
|Order_id    |    order_cd |            | order_id      |      order_cd |
----------------------------            ---------------------------------
| 60123456   |      1      |            |  60123456     |        1      |
| 60123456   |      2      |            |  60123456     |        2      |
| 60123456   |      3      |            |  60123456     |        3      |
| 60123456   |      4      |            |  60123456     |     missing   |
| 60123456   |      5      |            |  60123456     |     missing   |
| 60123654   |      1      |            |  60123654     |        1      |
| 60123654   |      2      |            |  60123654     |        2      |
| 60123654   |      3      |            |  60123654     |        3      |
| 60123654   |      4      |            |  60123654     |     missing   |
----------------------------            ---------------------------------

这是一个简化的示例,因为每个订单号可以有数千个 order_cd 的对应条目。

所以我需要一个查询来比较两个 table 和 return 不同的 order_id,其中 rtm_table 中缺少任何匹配的 order_cd .

问题之一是并非 order_table 中列出的所有订单都会在 rtm_table 中有条目。因此,需要做的第一件事是查询 rtm_table table 中的所有 order_id,因此我们只检查存在的那些。

我这样做了:

select * from 
       (select order_cd, order_id from order_table where order_cd != 'NET')      
       order_table
FULL OUTER JOIN 
       (select order_cd, order_id from rtm_table where order_suffix != 
       'NET') rtm_table

on order_table.order_cd = rtm_table.order_cd

where rtm_table.order_cd IS NULL

我使用其他帖子中的信息将其拼凑在一起。这 returned 是我需要的东西,除了我需要它来 return 不同的 order_id(不需要每个 order_cd 列出 1000 多次)我需要确保 returning order_id 根本没有 rtm_table 中的任何条目。

如有任何帮助,我们将不胜感激!

假设 rtm_table 中从来没有 order_table 中不存在的行 - 它始终是一个子集 - 您可以计算两个表中每个 order_id 的记录和比较它们:

select o.order_id
from (
  select order_id, count(order_cd) as cnt
  from order_table
  where order_cd != 'NET'
  group by order_id
) o
join (
  select order_id, count(order_cd) as cnt
  from rtm_table
  where order_suffix != 'NET' 
  group by order_id
) r
on r.order_id = o.order_id
and r.cnt < o.cnt;

如果 rtm_table 中没有匹配的记录,则连接将不匹配,因此不会包含这些记录。

您也可以使用 Gordon Linoff 左联接的变体,但基于两个表中出现的 ID 的交集:

select distinct t.order_id
from (
  select order_id from order_table
  where order_cd != 'NET'
  intersect
  select order_id from rtm_table
  where order_suffix != 'NET' 
) t
join order_table o on o.order_id = t.order_id
left join rtm_table r on r.order_id = o.order_id
and r.order_cd = o.order_cd
where r.order_cd is null;

甚至 existsnot exists:

select distinct o.order_id
from order_table o
where order_cd != 'NET'
and exists (
  select null from rtm_table r
  where r.order_id = o.order_id
  and order_suffix != 'NET' 
)
and not exists (
  select null from rtm_table r
  where r.order_id = o.order_id
  and r.order_cd = o.order_cd
  and order_suffix != 'NET' 
);

您可能想尝试各种方法来查看哪种方法最适合您的表、索引和数据 - 您没有说出您期望的命中数与未命中数,这可能会产生重大差异。

我会简单地使用 'minus' - 让 Oracle 为您完成肮脏的工作:

新版本:

select * from rtm_table
minus
select * from order_table

旧版本

select * from order_table
minus
select * from rtm_table;

这似乎适合我