2013-03-27 4 views
1

У меня есть две таблицы с одинаковыми столбцами, Код товара и Кол-во, для каждой таблицы:Как сделать полное внешнее соединение, используя старый стиль Oracle синтаксис

TABLE A     TABLE B 
--------------    ------------- 
X 2      X 1 
Y 1      S 2 
Z 5      Z 5 

Результат, который я стремлюсь получить что-то как это:

Table C 
--------------- 
X 2 1 
Y 1 0 
S 0 2 

нужно только элементы, где qty отличается в обеих таблицах (включая нули, которые должны быть показаны как нули

. Примечание: Я использую Oracle8, так что я не могу использовать ANSI ПОЛНАЯ ВНЕШНЯЯ ВСТУПЛЕНИЕ.

+1

Какая версия оракула? – Taryn

+4

Oracle8? В самом деле? Это уже давно не поддерживается. Вы действительно должны подумать о модернизации. –

+0

является (col1) уникальным? – Sebas

ответ

11

Edit, Поскольку вопрос относится только к Oracle 8, который не использует синтаксис ANSI, должно работать:

select col1, 
    nvl(a_col2, 0) as a_col2, 
    nvl(b_col2, 0) as b_col2 
from 
( 
    select a.col1, a.col2 as a_col2, b.col2 as b_col2 
    from TableA a, TableB b 
    where a.col1 = b.col1(+) 
    union 
    select b.col1, a.col2 as a_col2, b.col2 as b_col2 
    from TableA a, TableB b 
    where a.col1(+) = b.col1 
)  
where a_col2 <> b_col2 
    or (a_col2 is null or b_col2 is null) 

См SQL Fiddle with Demo. Это вернет:

| COL1 | A_COL2 | B_COL2 | 
-------------------------- 
| S |  0 |  2 | 
| X |  2 |  1 | 
| Y |  1 |  0 | 

Если вы используете версию Oracle, которая поддерживает синтаксис ANSI, то вы можете использовать следующие FULL OUTER JOIN:

select 
    coalesce(a.col1, b.col1) col1, 
    coalesce(a.col2, 0) a_col2, 
    coalesce(b.col2, 0) b_col2 
from tablea a 
full outer join tableb b 
    on a.col1 = b.col1 
where a.col2 <> b.col2 
    or (a.col2 is null or b.col2 is null); 

См SQL Fiddle with Demo

+0

It Wont Except Full Outer Присоединиться как синтаксис Я могу использовать знак (+) –

+2

@nayefharb Какую версию оракула вы используете? – Taryn

+0

Это самое лучшее преимущество новых объединений ANSI; мы не можем сделать эту половину так же легко в pre-9i Oracle, используя синтаксис '(+)'. – APC

2
select code, nvl(a.qty,0) a, nvl(b.qty,0) b 
from tableA a full join tableB b using(code) 
where decode(a.qty, b.qty, 0) is null 

fiddle

+0

-1: не работает на Oracle 8 –

+2

Эй, @ Давид, вы бы прекратили голосовать всех, кто отвечал перед ОП беспокоился о том, какую версию он использовал? Комментарий был бы достаточным, вместо того чтобы наказывать их за то, что пользователь не был на 15-летней платформе. –

+3

Ну, я не проводил судебно-медицинский анализ точных таймингов всего до голосования, и, к сожалению, я не могу отказаться от него ... видимо, он блокируется путем stackoverflow, если не отредактирован ответ. Sheesh! Во всяком случае, если вы хотите сделать небольшое редактирование для удовлетворения stackoverflow, я возьму downvote ... –

0

Следующий запрос должен работать право:

SELECT * FROM (
    SELECT nvl(a.c1, b.c2), nvl(a.col1, 0) qty1, nvl(b.col2, 0) qty2 FROM a FULL OUTER JOIN b ON a.c1 = b.c2 
) where qty1 != qty2; 

http://sqlfiddle.com/#!4/d37ff/5/0

2

Другой вариант:

select 
    full_list.item_code, 
    nvl(table_a.qty,0) table_a_qty, 
    nvl(table_b.qty,0) table_b_qty 
from 
    (select item_code from table_a 
    union 
    select item_code from table_b) full_list, 
    table_a, 
    table_b 
where 
    full_list.item_code = table_a.item_code(+) and 
    full_list.item_code = table_b.item_code(+) 
+0

-1 а? Любая причина? –

+4

Не уверен, возможно, возмездие за то, что кто-то еще проголосовал, кто ответил, прежде чем они узнали, что система была из темных веков. –

+1

SQL-скрипт не делает 8i, поэтому его релевантность будет немного подозрительной. Во всяком случае, толстая отвлекающая ошибка пальца исправлена ​​в ответе –

4

Другой написание запроса, который должен работать в 8 и (вероятно, более ранние версии).

Он не использует ни один из FULL JOIN не ужасный синтаксис для присоединений, поэтому он должен работать, даже если обновление обесценивает его.

Предполагая, что нет Нулевые уже на столах, вам не нужно будет COALESCE() или NVL() либо:

SELECT a.col1, 
     a.col2 AS a_col2, 
     b.col2 AS b_col2 
FROM TableA a, TableB b 
WHERE a.col1 = b.col1 
    AND (a.col2 <> b.col2 
    OR a.col2 IS NULL 
    OR b.col2 IS NULL 
    ) 

UNION ALL 

SELECT col1, col2, 0 
FROM TableA a 
WHERE NOT EXISTS 
     (SELECT * 
      FROM TableB b 
      WHERE a.col1 = b.col1 
     ) 

UNION ALL 

SELECT col1, 0, col2 
FROM TableB b 
WHERE NOT EXISTS 
     (SELECT * 
      FROM TableA a 
      WHERE a.col1 = b.col1 
     ) ; 

тесты на SQL-Fiddle

Смежные вопросы