Как сравнить два набора строк в Oracle? - PullRequest
1 голос
/ 14 июня 2019

Итак, проблема в том, что у меня есть два результата (например, число):

СОП1: 10 11

RES2: 10 13

Мне нужно сравнить такие, как если RES1 в RES2 и RES2 в RES1.

Я бы хотел получить результат как:

RES3: 11 13

Как мне это сделать?

Я пытался

RES1 МИНУС RES2 UNION RES2 МИНУС RES1

но этот подход очень медленный, потому что моя таблица содержит миллионы строк ...

Ответы [ 3 ]

0 голосов
/ 14 июня 2019

Являются ли эти значения уникальными в RES1 или RES2? Тогда вы можете попробовать подсчитать:

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

Если он не уникален, вам нужно добавить отчетливый по обе стороны союза, что делает его намного медленнее

0 голосов
/ 14 июня 2019

Почему бы не использовать один из поставляемых пакетов. 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 не равно нулю -> запись существует в обеих таблицах, но имеет разные значения

0 голосов
/ 14 июня 2019

солютин 1:

попробуйте UNION ALL вместо UNION.

почему UNION ALL лучше, чем UNION, вы можете прочитать здесь: В чем разница между UNION и 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...