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

时间:2016-02-02 17:40:25

标签: sql oracle compare missing-data

我需要比较两个表,并找到缺少数据的条目。

示例:

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的相应条目。

所以我需要一个查询来比较两个表并返回不同的order_id,其中rtm_table中缺少任何匹配的order_cd。

其中一个问题是order_table中列出的所有订单都不会在rtm_table中包含条目。因此,首先需要查询所有order_id的rtm_table表,因此我们只检查那些存在的。

我这样做了:

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

我用其他帖子的信息拼凑了这个。这返回了我需要的东西,除了我需要它来返回不同的order_id(不需要为每个order_cd列出1000次以上)并且我需要确保它没有返回没有任何条目的order_id在rtm_table中。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

我只想使用'减' - 让Oracle为你做脏事:

新版本:

select * from rtm_table
minus
select * from order_table

旧版

select * from order_table
minus
select * from rtm_table;

这似乎适合我

答案 1 :(得分:0)

假设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' 
);

您可能想尝试各种方法来查看哪种方法最适合您的表格,索引和数据 - 您还没有说出您预期会有多少点击与未命中,这可能会产生重大影响。