如何在Oracle中比较两组行?

时间:2019-06-14 08:13:37

标签: oracle plsql

所以,问题是我有两个结果(例如数字):

RES1: 10 11

RES2: 10 13

我需要比较一下RES2中的RES1和RES1中的RES2。

我希望得到这样的结果:

RES3: 11 13

我该怎么做?

我尝试了

RES1减去RES2 联盟 RES2减去RES1

但是这种方法非常慢,因为我的表包含了数百万行...

3 个答案:

答案 0 :(得分:0)

解决方案1:

尝试使用UNION ALL代替UNION

为什么UNION ALLUNION更好,您可以在这里阅读:What is the difference between UNION and UNION ALL?

解决方案2:

您可以尝试使用full outer join

select coalesce(a.id,b.id)
from a
full outer join b on a.id = b.id
where a.id is null
or b.id is null

示例:http://www.sqlfiddle.com/#!4/88f81/3

答案 1 :(得分:0)

RES1或RES2中的那些值是否唯一?然后您可以尝试计数:

SELECT col
FROM (
    SELECT col FROM RES1
    UNION ALL
    SELECT col FROM RES2
)
GROUP BY col
HAVING COUNT(1) = 1

如果它不是唯一的,则必须在联合的两边都添加一个不同的字符,这会使它变慢很多

答案 2 :(得分:0)

为什么不使用提供的软件包之一。 DBMS_COMPARISON 该包允许比较和同步表。仅要求表具有索引。

1)创建差异数据集

create table to_compare2 as (select OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID, OBJECT_TYPE, case when mod(object_id,18) = 0 then  CREATED +1 else CREATED end  CREATED  from all_objects where mod(object_id,6) = 0 );
CREATE table to_compare1 as (SELECT OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID, OBJECT_TYPE, case when mod(object_id,12) = 0 then  CREATED +1 else CREATED end  CREATED  FROM ALL_OBJECTS where mod(object_id,3) = 0 );

2)创建索引。

  CREATE UNIQUE INDEX to_compare1_idx  on  to_compare1(object_id);
  CREATE UNIQUE INDEX to_compare2_idx  on  to_compare2(object_id);

3)准备比较上下文

BEGIN
  DBMS_COMPARISON.create_comparison (
    comparison_name    => 'MY_COMPARISION',
    schema_name        => user,
    object_name        => 'to_compare1',
    dblink_name        => NULL,
    remote_schema_name => null,
    remote_object_name => 'to_compare2');
END;
/

4)执行比较并检查结果。

DECLARE
  v_scan_info  DBMS_COMPARISON.comparison_type;
  v_result     BOOLEAN;
BEGIN
  v_result := DBMS_COMPARISON.compare (
                comparison_name => 'MY_COMPARISION',
                scan_info       => v_scan_info,
                perform_row_dif => TRUE
              );

  IF NOT v_result THEN
    DBMS_OUTPUT.put_line('Differences. scan_id=' || v_scan_info.scan_id);
  ELSE
    DBMS_OUTPUT.put_line('No differences.');
  END IF;
END;
/

4)结果

SELECT *
FROM   user_comparison_row_dif
WHERE  comparison_name = 'MY_COMPARISION';

如果local_rowid不为空并且remote_rowid为空->在表_1中记录退出
如果local_rowid为空且remote_rowid is不为空->表_2中的记录退出
如果local_rowid不为空,并且remote_rowid不为空->两个表中都存在记录,但是其值不同