2013-07-01 6 views
2

Я пытаюсь найти записи, которые существует в таблице A, но не в таблице В. Если имеется только один столбец, чтобы проверить, то я могу использоватьпоиск записей, не существует в другой таблице оракула

select col_A,col_B,......from A where col_A not in (select Col_A from B). 

Но у меня есть четыре столбца, которые нужно проверить.

я сделал что-то вроде этого, который работает, но не является идеальным способом

select col_A,col_B,col_C,col_D from A where col_A||col_B||col_C||col_D not in (select col_A||col_B||col_C||col_D from B) 

, а также он занимает много времени, чтобы возвращать результаты в случае большого объема данных.

Пожалуйста, предложите правильный способ сделать это.

Спасибо .....

+0

Какая общая колонка в таблице A и B? – user75ponic

ответ

5

Из документации Oracle

http://docs.oracle.com/cd/E11882_01/server.112/e26088/queries004.htm#SQLRF52341

«МИНУС Пример Следующий оператор объединяет результаты с оператором МИНУС, который возвращает только уникальные строки, возвращаемые первого запроса, но а не вторым: «

SELECT product_id FROM inventories 
MINUS 
SELECT product_id FROM order_items; 

Ваши требования немного сложнее. Я полагаю, что сочетание cols_a, cols_b, cols_c, cols_d является уникальным для записи в таблице А. В этом случае, следующий код должен решить проблему:

create table A (
    cols_date DATE, 
    cols_a NUMBER, 
    cols_b NUMBER, 
    cols_c NUMBER, 
    cols_d NUMBER 
); 

create table B (
    cols_a NUMBER, 
    cols_b NUMBER, 
    cols_c NUMBER, 
    cols_d NUMBER 
); 

insert into A (cols_date, cols_a, cols_b, cols_c, cols_d) values (sysdate, 1, 1, 1, 1); 
insert into A (cols_date, cols_a, cols_b, cols_c, cols_d) values (sysdate, 2, 2, 2, 2); 

insert into B (cols_a, cols_b, cols_c, cols_d) values (2, 2, 2, 2); 
insert into B (cols_a, cols_b, cols_c, cols_d) values (3, 3, 3, 3); 
commit; 

select a.cols_date, a.cols_a, a.cols_b, a.cols_c, a.cols_d from (
    select cols_a, cols_b, cols_c, cols_d 
    from A 
    minus 
    select cols_a, cols_b, cols_c, cols_d 
    from b 
) ma, a 
where 1=1 
    and ma.cols_a = a.cols_a 
    and ma.cols_b = a.cols_b 
    and ma.cols_c = a.cols_c 
    and ma.cols_d = a.cols_d; 

Результат

COLS_DATE     COLS_A  COLS_B  COLS_C  COLS_D 
--------------------- ---------- ---------- ---------- ---------- 
01.07.2013 13:20:02   1   1   1   1 

НЕ СУЩЕСТВУЕТ также решить эту проблему. Это утверждение имеет лучший план выполнения, а затем версию MINUS.

Благодаря Дэвиду Олдриджу за это решение.

select 
    cols_date, 
    cols_a, cols_b, cols_c, cols_d 
from 
    a 
where 
    not exists (
    select 1 
    from b 
    where 1=1 
    and b.cols_a = a.cols_a 
    and b.cols_b = a.cols_b 
    and b.cols_c = a.cols_c 
    and b.cols_d = a.cols_d   
); 
+0

Я также хочу отображать столбцы, которые существуют только в таблице A, поэтому я считаю, что минус здесь не будет работать. – Harry

+0

Вы хотите увидеть что-то вроде этого? создать таблицу A ( col_a NUMBER, col_b NUMBER ); создать таблицу B ( col_a NUMBER, col_c NUMBER ); выбери имя_столбец из user_tab_columns , где table_name = 'А' минуса выбери имя_столбец из user_tab_columns , где table_name = 'В' ; Результат: COL_B –

+0

@ Olaf H. Спасибо за ответ, Не совсем. – Harry

1
WITH mine AS (
    SELECT cols_a, cols_b, cols_c, cols_d FROM a 
    MINUS 
    SELECT cols_a, cols_b, cols_c, cols_d FROM b 
) 
SELECT a.cols_date, a.cols_a, a.cols_b, a.cols_c, a.cols_d 
FROM a NATURAL JOIN mine 
3

Там в неявной отличие от МИНУС, что вы, вероятно, хотите, чтобы избежать.

Конструкция НЕ СУЩЕСТВУЕТ, вероятно, будет работать как хэш-анти-соединение, что было бы очень эффективно.

select 
    col1, 
    col2, 
    col3, 
    ... etc 
from 
    table_a a 
where 
    not exists (
    select null 
    from table_b b 
    where a.col1 = b.col1 and 
      a.col2 = b.col2 and 
      a.col3 = b.col3 and 
      a.col4 = b.col4) 
Смежные вопросы