Reputation: 37
So, the problem is that i have two results (eg. number):
RES1: 10 11
RES2: 10 13
I need to compare those like if RES1 in RES2 and RES2 in RES1.
I would like to have result like:
RES3: 11 13
How do i do that?
I tried
RES1 MINUS RES2 UNION RES2 MINUS RES1
but this approach is very slow, becouse my table contains milions of rows...
Upvotes: 1
Views: 710
Reputation: 6346
Why not to use one of supplied packages. DBMS_COMPARISON The Package allows to compare and sync tables. It's only required that tables have an index.
1) create diff datasets
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 indexes.
CREATE UNIQUE INDEX to_compare1_idx on to_compare1(object_id);
CREATE UNIQUE INDEX to_compare2_idx on to_compare2(object_id);
3) Prepare comparision context
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) Execute comparison and check results.
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) Results
SELECT *
FROM user_comparison_row_dif
WHERE comparison_name = 'MY_COMPARISION';
if local_rowid
is not null and remote_rowid
is null -> record exit in table_1
if local_rowid
is null and remote_rowid is
not null -> record exit in table_2
if local_rowid
is not null and remote_rowid
is not null -> record exist in both tables but it has different values
Upvotes: 1
Reputation: 36
Are those Values unique in RES1 or RES2? Then you could try counting:
SELECT col
FROM (
SELECT col FROM RES1
UNION ALL
SELECT col FROM RES2
)
GROUP BY col
HAVING COUNT(1) = 1
If it is not unique, you'd have to add a distinct on both sides of the union, which makes it a lot slower
Upvotes: 0
Reputation: 3396
solutin 1:
try UNION ALL
instead of UNION
.
why UNION ALL
is better then UNION
you can read here: What is the difference between UNION and UNION ALL?
solutin 2:
you can try to use 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
Example: http://www.sqlfiddle.com/#!4/88f81/3
Upvotes: 0