使用传统的join子句与(+)运算符

时间:2017-01-30 03:40:58

标签: sql oracle outer-join

我真的遇到了来自JustLee数据库的SQL问题。不是在找任何人做我的作业,但不幸的是我被卡住了......

  

问题:显示他们撰写的所有作者和书籍。包括尚未完成书籍编写的作者。包括作者姓氏,作者名字,isbn和书名。将传统的join子句与(+)运算符一起使用。

我最好的猜测是:

select lname, fname, isbn, title
from author a, bookauthor ba, books b
where a.authorid(+) = ba.authorid
and ba.isbn(+) = b.isbn
order by 1,2,3,4;

但我得到一个含糊不清的列错误。任何帮助将非常感激。谢谢!

3 个答案:

答案 0 :(得分:4)

您需要在SELECT列表中限定不明确的列名:

select lname, fname, b.isbn, title
from author a, bookauthor ba, books b
where a.authorid(+) = ba.authorid
and ba.isbn(+) = b.isbn
order by 1,2,3,4;

通常,优先选择限定select中的所有列,除了清楚列来自哪个表。我还建议您切换到现代JOIN语法,并在ORDER子句中明确列出列:

select a.lname, a.fname, b.isbn, b.title
from author a
LEFT JOIN bookauthor ba
ON a.authorid = ba.authorid
LEFT JOIN books b
and ba.isbn = b.isbn
order by a.lname, a.fname, b.isbn, b.title; 

答案 1 :(得分:1)

如果数据模型正确,则authorid应为author中的主键和bookauthor中的外键。同样,isbn应该是books中的主键和bookauthor中的外键。您主要是为作者查询,并且 - 可能 - 您可能有作者没有写过任何书籍,因此他们可能会在author表中但不在bookauthor表中(尽管我会质疑为什么他们在author表中开始。问题陈述说“他们还没有写完他们的书”,所以让我们继续吧。

要让只显示在author表格中但不在bookauthor中的作者,您需要left outer joinauthor之间的bookauthor。使用Oracle专有表示法((+)表示法),(+)应位于相等的右侧侧:

... from author a, bookauthor ba, books b
where a.authorid = ba.authorid(+)
  and ba.isbn    = b.isbn

注意两件事:

对于左连接,(+)在右侧。要记住它:“外部”连接为左侧表格中存在的authorid值创建“虚构”行,但在右侧则缺少。因此,您需要将这些“化妆”或“虚构”行添加到右侧(不在左侧)的表中。所以(+)在右边。

对于isbn,内连接应该足够 - bookauthor表中不应该有与books表中的书不对应的书。 (当然,如果表格具有正确的外键和主键,如上所述。)

注意:我非常怀疑一本想要强迫你学习旧的,不推荐的(+)语法的书(更常见的是“通过WHERE子句中的条件连接语法”)与使用ON或USING子句的现代首选ANSI标准语法相反。

答案 2 :(得分:0)

您选择的一个或多个列存在于多个表中。你必须对它们进行限定。

看起来isbnbooks表格中都存在bookauthor列,因此您应该选择isbn或{{b.isbn,而不是选择ba.isbn。 1}}。