我遇到了一个问题,即带有过滤器的 Oracle ANSI 完全外部联接没有按照我的预期返回结果。我创建了一个简单的例子来解释我在做什么和看到......
Table 1 - MUPPET
ID NAME
1 Kermit the Frog
2 Fozzie Bear
3 Mrs. Piggy
4 Beaker
5 Animal
6 Swedish Chef
Table 2 - PHONE
ID MUPPET_ID PHONE VALID
1 1 1111111111 Y
2 1 2222222222 N
3 2 3333333333 Y
4 4 4444444444 Y
5 5 5555555555 Y
6 6 6666666666 Y
7 6 7777777777 N
8 8 8888888888 Y
从这些表中,我想选择所有布偶和所有有效的电话号码。我想要所有的布偶,无论它们是否有电话号码,并且我想选择所有有效的电话号码,无论它们是否与布偶相关联。这是我希望工作的查询......
SELECT m.id muppet_id,
m.name,
p.id phone_id,
p.phone,
p.valid
FROM muppet m
FULL OUTER JOIN
phone p
ON (M.ID = P.MUPPET_ID AND P.VALID = 'Y')
但这里的结果包括无效电话,即使我在外连接过滤器中没有指定无效电话
MUPPET_ID NAME PHONE_ID PHONE VALID
1 Kermit the Frog 1 1111111111 Y
2 2222222222 N
2 Fozzie Bear 3 3333333333 Y
4 Beaker 4 4444444444 Y
5 Animal 5 5555555555 Y
6 Swedish Chef 6 6666666666 Y
7 7777777777 N
8 8888888888 Y
3 Mrs. Piggy
我终于能够在完整外连接的左侧使用子选择获得我正在寻找的结果
SELECT m.id muppet_id,
m.name,
p.id phone_id,
p.phone,
p.valid
FROM muppet m
FULL OUTER JOIN
(SELECT id,
phone,
valid,
muppet_id
FROM phone
WHERE valid = 'Y') p
ON (M.ID = P.MUPPET_ID)
……结果……
MUPPET_ID NAME PHONE_ID PHONE VALID
1 Kermit the Frog 1 1111111111 Y
2 Fozzie Bear 3 3333333333 Y
4 Beaker 4 4444444444 Y
5 Animal 5 5555555555 Y
6 Swedish Chef 6 6666666666 Y
8 8888888888 Y
3 Mrs. Piggy
但我不明白为什么我必须以这种方式查询。有人可以帮我解释一下为什么我使用过滤器的初始外部连接查询不能按预期工作吗?
编辑:
更有趣的是。当我运行此查询时,我按预期获得了 6 条记录
select valid from (
SELECT m.id muppet_id,
m.name,
p.id phone_id,
p.phone,
p.valid
FROM muppet m
FULL OUTER JOIN
phone p
ON (M.ID = P.MUPPET_ID AND P.VALID = 'Y')
) where valid = 'Y'
但是当我运行它时,我没有返回任何记录
select valid from (
SELECT m.id muppet_id,
m.name,
p.id phone_id,
p.phone,
p.valid
FROM muppet m
FULL OUTER JOIN
phone p
ON (M.ID = P.MUPPET_ID AND P.VALID = 'Y')
) where valid <> 'Y'
也许这是 Oracle 优化器或驱动程序的问题?