Sql 为什么不能将OR或IN与外部联接操作一起使用?

Sql 为什么不能将OR或IN与外部联接操作一起使用?,sql,oracle,Sql,Oracle,如果受此问题启发,在Oracle SQL数据库中使用以下查询: 我将获得错误: ORA-01719:在或的操作数中不允许外部联接运算符+ 这应该可以解决这个问题: SELECT p.Name, a.Attribute FROM People p LEFT OUTER JOIN Attributes a ON p.PersonID = a.PersonID AND a.Attribute IN ('Happy','Grouchy') AND p.person_id IN ('Elmo', 'Osc

如果受此问题启发,在Oracle SQL数据库中使用以下查询:

我将获得错误:

ORA-01719:在或的操作数中不允许外部联接运算符+

这应该可以解决这个问题:

SELECT p.Name, a.Attribute
FROM People p
LEFT OUTER JOIN Attributes a
ON p.PersonID = a.PersonID AND a.Attribute IN ('Happy','Grouchy') AND p.person_id IN ('Elmo', 'Oscar')

有人能解释一下第一个版本调用错误的原因吗?实际的区别是什么

顺便说一下,您已经在那里定义了一个内部联接

通过在右边的表中有一个子句,它必须同时满足这两个条件

SELECT p.Name, a.Attribute
FROM People p
LEFT OUTER JOIN Attributes a
ON p.PersonID = a.PersonID 
WHERE a.Attribute IN ('Happy','Grouchy') -- This means that the right side must exist also
AND p.person_id IN ('Elmo', 'Oscar') 

要么使用内部联接,要么将其作为AND子句移动到WHERE,这只是Oracle多年前实现+运算符的方式:有些东西不适用于它。另一个例子是完全外部联接,它只能借助于带有+运算符的并集来表示

有人能解释一下第一个版本调用错误的原因吗

这正是Oracle决定这样做的方式:在使用外部联接时调用错误:

实际的区别是什么

在这里,我可以给你一个更全面的解释,我希望

与内部联接不同,外部联接的设计允许您从示例表中的表A中选择所有行,并将表B中的相应数据联接到相同的结果行(如果存在)。这意味着外部联接允许不存在的表B数据

当您将表B中的列放入WHERE子句时,您使它们的存在成为必需的,如果您比较它们,它们必须存在,从而有效地使您的联接成为内部联接

另一方面,当您编写以下代码时:

LEFT OUTER JOIN Attributes a
ON p.PersonID = a.PersonID AND a.Attribute IN ('Happy','Grouchy') AND p.person_id IN ('Elmo', 'Oscar')
这相当于你写了以下内容:

LEFT OUTER JOIN (SELECT *
                   FROM Attributes
                  WHERE Attribute IN ('Happy','Grouchy')
                ) a   ON (p.PersonID = a.PersonID)
WHERE p.person_id IN ('Elmo', 'Oscar')

因此,您已恢复使用外部联接。

您的查询是内部联接,因此您不妨编写:

SELECT p.Name, a.Attribute
FROM People p INNER JOIN
     Attributes a
     ON p.PersonID = a.PersonID 
WHERE a.Attribute IN ('Happy','Grouchy') AND
      p.person_id IN ('Elmo', 'Oscar');
由于.Attribute中的空值,WHERE子句将撤消对LEFT JOIN的任何使用

如果您想要一个甚至没有匹配项的人,那么您确实想要一个左联接,并将第二个表上的条件移动到on子句:


第一个查询的副本,如果它运行的话,将等同于只使用内部联接,所以尝试让该查询按原样工作是多余的。在ON子句中将a.属性置于条件中,并在WHERE子句中将p.Person\u Id置于条件中。这允许左外部联接按预期运行,而不会意外导致隐式内部联接,并且应该允许查询运行。谢谢。如果这是一个答案,我会接受的。我不知道这个查询怎么会导致上面提到的错误。查询中没有+。它似乎按原样工作:因此,如果我想找到一个没有属性的人,我可以在“Happy”、“grouch”或a.attribute中使用a.attribute吗?
SELECT p.Name, a.Attribute
FROM People p INNER JOIN
     Attributes a
     ON p.PersonID = a.PersonID 
WHERE a.Attribute IN ('Happy','Grouchy') AND
      p.person_id IN ('Elmo', 'Oscar');
SELECT p.Name, a.Attribute
FROM People p INNER JOIN
     Attributes a
     ON p.PersonID = a.PersonID AND
        a.Attribute IN ('Happy', 'Grouchy')
WHERE p.person_id IN ('Elmo', 'Oscar');