简体   繁体   English

如何使用旧式Oracle语法进行完全外部联接

[英]How to do a Full Outer Join using old style Oracle syntax

I have two tables with the same columns, Item Code and Qty, for each Table: 我有两个表,每个表都有相同的列,分别是项代码和数量:

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

The result that I am aiming to get is something like this: 我想要得到的结果是这样的:

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

I only need the items where qty differs in both tables (including the nulls which should be shown as zeroes. 我只需要两个表中qty不同的项目(包括应该显示为零的null)。

Note: I am using Oracle8 so I can't use the ANSI FULL OUTER JOIN. 注意:我正在使用Oracle8,所以不能使用ANSI FULL OUTER JOIN。

Edit, Since the question is specific to Oracle 8 which does not use ANSI syntax, the following should work: 编辑,由于该问题是特定于不使用ANSI语法的Oracle 8的,因此以下各项应适用:

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)

See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle This will return: 这将返回:

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

If you are using a version of Oracle that supports ANSI syntax then you can use the following FULL OUTER JOIN : 如果使用的是支持ANSI语法的Oracle版本,则可以使用以下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);

See SQL Fiddle with Demo 参见带有演示的SQL Fiddle

Another writing of the query which should work in 8 and (probably earlier versions). 该查询的另一种写法应在8及更高版本(可能是较早的版本)中运行。

It uses neither FULL JOIN not the horrible (+) syntax for joins so it should work even when an upgrade deprecates it. 它既不使用FULL JOIN也不使用可怕的(+)语法进行联接,因此即使升级已弃用它,它也应能正常工作。

Assuming that there are no Nulls already on the tables, you won't need COALESCE() or NVL() either: 假设表上没有Null,则您将不需要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
        ) ; 

Tests at SQL-Fiddle SQL-Fiddle中进行测试

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 小提琴

Another option: 另外一个选项:

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(+)

The following query should work just right: 以下查询应该可以正常工作:

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 http://sqlfiddle.com/#!4/d37ff/5/0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM