将WHERE子句与NATURAL JOIN SQL结合使用?

Wit*_*RIT 0 mysql sql join

我正在阅读一本关于SQL的书,我被困在一个与数据库模式相关的示例中,如下图所示. 数据库模式

下面的示例解决了书中所述的查询:

假设我们希望回答查询"列出教师的名字以及他们教授的课程的标题."查询可以用SQL编写,如下所示:

select name , title
from instructor natural join teaches , course
where teaches.course id = course.course id;
Run Code Online (Sandbox Code Playgroud)

现在这本书说明了这一点

"请注意,where子句中的teaches.course id指的是自然连接结果的课程id字段,因为该字段又来自教学关系."

这本书再次在BOLD中说:

"不可能使用包含原始关系名称的属性名称(例如instructor.name或teaches.course id)来引用自然连接结果中的属性;但是,我们可以使用属性名称,例如名称和课程ID ,没有关系名称."

(参考上面的查询)如果不可能,那么作者如何能够将查询编写为

teaches.course id = course.course id
Run Code Online (Sandbox Code Playgroud)

如何将teaches.course引用自然连接属性"课程",作者如此模糊地提出了他的论点.请向我解释作者的观点.

Gor*_*off 5

忽略这本书所说的内容NATURAL JOIN.避免它. NATURAL JOIN是一个等待发生的错误.为什么?连接键只是通过表中列的命名约定来定义 - 使用恰好具有相同名称的任何列.实际上,NATURAL JOIN 忽略了正确定义的FOREIGN KEY关系; 它们隐藏了实际用于匹配的键.

所以,要明确并使用ONUSING条款.这些是关于正在使用的密钥的明确,代码更易理解和可维护.

然后,遵循一个简单的规则: 永远不要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;
Run Code Online (Sandbox Code Playgroud)

请注意,没有where子句,所有列都是合格的,这意味着它们指定了它们来自的表.

此外,我没有instructor_idteaches表中看到一列,所以这只是合理代码的样子.