【发布时间】:2013-06-22 10:53:52
【问题描述】:
我遇到了一个问题,即带有过滤器的 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 优化器或驱动程序的问题??
【问题讨论】:
-
当您使用完全外连接时,您要求数据库连接所有记录并保留所有不满足连接条件的记录。在您的示例中,
valid='Y'是条件的一部分,因此其他两条记录保持未连接状态。这是预期的结果。 -
没错,
valid = 'Y'条件应该在where子句中指定,而不是on子句中。 -
GriffeyDog -
valid = 'Y'的 where 子句不会返回 Mrs. Piggy 的最后一条记录,所以这也不起作用 -
@haki - 我不认为我跟随。如果我在左连接中提供
valid = 'Y',它只会返回带有“Y”的有效记录。在这个外部连接中,它也返回不遵循我在 ON 子句中放入的“N”条记录
标签: oracle filter oracle11g ansi outer-join