我正在阅读一本关于SQL的书,我被困在一个与数据库架构相关的示例中,如下图所示。
以下示例解决了书中所述的查询:
假设我们希望回答查询“列出教师姓名 以及他们教授的课程的标题。“查询可以写成 SQL如下:
select name , title
from instructor natural join teaches , course
where teaches.course id = course.course id;
现在这本书说明了
“请注意teaches.course id 在where子句中引用自然连接结果的课程id字段,因为该字段又来自教学关系。 “
这本书再次在BOLD中说:
“不可能使用包含原始关系名称的属性名称(例如instructor.name或teaches.course id)来引用自然连接结果中的属性;但是,我们可以使用属性名称,例如 名称和课程ID,没有关系名称。“
(参考上面的查询)如果不可能那么作者怎么能够将查询写成
teaches.course id = course.course id
teaches.course如何引用自然连接属性“课程”,作者如此暧昧地提出了他的论点。请解释我作者的观点。
答案 0 :(得分:5)
忽略本书对NATURAL JOIN
的评论。避免它。 NATURAL JOIN
是一个等待发生的错误。为什么?连接键只是通过表中列的命名约定来定义 - 使用恰好具有相同名称的任何列。实际上,NATURAL JOIN
会忽略正确定义的FOREIGN KEY
关系;它们隐藏了实际用于匹配的键。
因此,请明确并使用ON
或USING
子句代替。这些是关于正在使用的密钥的明确,代码更易理解和可维护。
然后,遵循一个简单的规则:从不在FROM
子句中使用逗号; 始终使用显式JOIN
语法。
因此,编写查询的好方法是这样的:
select i.name, c.title
from instructor i inner join
teaches t
on t.instructor_id = i.instructor_id inner join
course c
on t.course_id = i.course_id;
请注意,没有where
子句,并且所有列都是合格的,这意味着它们指定了它们来自的表。
另外,我在instructor_id
表中没有看到teaches
列,所以这只是合理代码的示例。