使用多个键检查外连接查询中的非匹配行

时间:2016-10-21 13:27:52

标签: sql oracle

我有两个表A和B,以及一个类似的查询:

Select * from A left join B 
on A.key1=B.Key1
and A.key2=B.Key2

我是否可以仅使用一个连接查询根据Key1 OR Key2识别不匹配的行?

我知道我可以使用:

Select * from A left join B 
    on A.key1=B.Key1
    and A.key2=B.Key2
    where B.Key1 is null or B.Key2 is null 

但是它只告诉我表A中的表1中的Key1 / Key2不在表B中,但是并没有告诉我表B中没有出现哪个Key。

谢谢!

4 个答案:

答案 0 :(得分:3)

您需要完全外部联接

Select * 
from A 
full outer join B on A.key1=B.Key1
                 and A.key2=B.Key2
where B.Key1 is null or B.Key2 is null 
   or A.Key1 is null or A.Key2 is null 

答案 1 :(得分:1)

您可以使用" OR" ina join:

Select * 
from A 
left join B 
on A.key1=B.Key1
or A.key2=B.Key2

或者这是你想要的那种逻辑?

select A.*,
       case
           when not exists (select 1 from B where B.key1 = A.key1) 
               and not exists (select 1 from B where B.key2 = A.key2)
               then 'None'
           when exists (select 1 from B where B.key1 = A.key1) 
               and exists (select 1 from B where B.key2 = A.key2)
               then 'Both'
           when not exists (select 1 from B where B.key1 = A.key1) 
               and exists (select 1 from B where B.key2 = A.key2)
               then 'Key2'
           when not (select 1 from B where B.key1 = A.key1) 
               and not exists (select 1 from B where B.key2 = A.key2)
               then 'Key1'
       end as Key_status
from A

答案 2 :(得分:1)

如果您希望版本为UNION

SELECT A.key1 AS key1, A.key2 AS key2 FROM A
UNION
SELECT B.key1 AS key1, B.key2 AS key2 FROM B
MINUS 
SELECT A.key1 AS key1, A.key2 AS key2 FROM A INNER JOIN B ON A.key1=B.Key1 AND A.key2=B.Key2

答案 3 :(得分:-1)

首先必须创建一个primary_key(A中的id)&两个表中的foregin_key(在B中为id),然后,您可以像这样实现它:

在这里,我根据您的要求动态创建了表格,看看:

DECLARE @table1 TABLE
( id INT, name NVARCHAR(20), key1 NVARCHAR(20), key2 NVARCHAR(20))
DECLARE @table2 TABLE
( id INT, key1 NVARCHAR(20), key2 NVARCHAR(20))

INSERT INTO @table1 VALUES
('1'     ,'name1',  'somekey1',    'secondo21'),
('2'     ,'name2',  'somekey10',   'seconn3'),
('3'     ,'name3',  'somekey3',    'city3'),
('4'    ,'name4',  'postal4',    'city4'),
('5'    ,'name5',  'postal55',    'city5'),
('6'    ,'name6',  'postal76',    'city56'),
('7'    ,'name7',  'postal77',    'city567')

INSERT INTO @table2 VALUES
('1',     'somekey1',    'secondo21'),
('8',    'postal2',    'seconn38'),
('3',      'somekey3',    'city3'),
('5',     'postal5',    'city5'),
('6'    ,'postal86',    'city96'),
('7'    ,'postal77',    'city577')

SELECT *,
CASE WHEN A.key1 = B.key1 AND A.key2 = B.key2 THEN 'All Matched' 
WHEN A.key1 = B.key1 AND A.key2 <> B.key2 THEN 'key2 Unmatched' 
WHEN A.key1 <> B.key1 AND A.key2 = B.key2 THEN 'key1 Unmatched' 
WHEN A.key1 <> B.key1 AND A.key2 <> B.key2 THEN 'key1 & key2 Both Unmatched' 
ELSE 'No row present in tblB with id '+ CONVERT(VARCHAR,A.id)
END  'unmatched'
 FROM @table1 A LEFT JOIN @table2 B ON A.id = B.id

希望它有所帮助。 :)