2012-02-06 72 views
1

以这两个例子表:Oracle SQL - 连接不存在的行吗?

Table A 
Name FirstOrLast 
Jeremy First 
Smith Last 
Mark First 
David First 


Table B 
Name 
Jeremy 
Smith 
Mark 
David 
Jones 
Jack 

我想输出是这样的:只输出的名字,但如果如果它是一个姓或名,输出也无妨表A不记录。正确的输出为:

Jeremy 
Mark 
David 
Jones 
Jack 

我试图实现这一点与外连接,就像这样:

select 
    B.Name 
from 
    A, B 
where 
    A.name = B.name(+) and 
    A.FirstOrLast = 'First'; 

,但没有运气。我怎样才能做到这一点?

回答

4

当您执行左外连接,也没有纪录Aa.firstOrLast将是无效的。当你在这,你还不如切换到标准语法加入:

select 
    B.Name 
from 
    B 
left outer join A on A.name = B.name 
where 
A.firstOrLast is null or A.firstOrLast = 'First'; 

然而,旧的语法也应该工作:

select 
    B.Name 
from 
    A, B 
where 
    A.name = B.name(+) and 
    (A.firstOrLast is null or A.firstOrLast = 'First'); 
+0

这很好。两个问题:为什么“标准”语法更好(我的公司使用(+)语法,但我对sql很新,所以我愿意改变我的样式)。二,你能解释一下A.name = B.name(+)在这里完成的事情吗? – Jeremy 2012-02-06 22:22:47

+2

@Jeremy旧的语法只适用于Oracle;新的语法适用于大多数现代RDBMS。在SQL进行了标准化之前,RDBMS供应商为此定义了自己的语法:例如,Sybase使用了'A.name * = B.name'。外连接标记'(+)'表示“即使右边的行不存在,也不要删除左边的行”。 – dasblinkenlight 2012-02-06 22:26:30

2

试试这个:

SELECT B.Name 
FROM B LEFT JOIN A ON B.Name = A.Name 
WHERE A.FirstOrLast = 'First' OR A.Name IS NULL; 
+0

这使与我的输出相同(有或没有我的外连接)。最后的A.name应该是A.FirstOrLast,但是我在我的问题中犯了同样的错误。 – Jeremy 2012-02-06 22:19:28

+0

@Jeremy。这个答案和你接受的答案完全一样,为什么说它不起作用? – gdoron 2012-02-07 05:58:21

+0

我不知道。我确定“或A.Name是NULL”不在那里,但看起来它没有被编辑过。我很困惑。好吧,无论如何我都会赞成,因为这确实是一个完美的答案。 – Jeremy 2012-02-07 22:43:05

0
select b.name 
from b 
union 
select a.namfe 
from a 
where a.firstOrLast = 'First' 
0
SELECT Name 
FROM B 
MINUS 
SELECT Name 
FROM A 
WHERE FirstOrLast <> 'First'