Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 查询和修改数据 » 连接:从多个表检索数据 » 键连接

 

在有多个外键关系时的键连接

SQL Anywhere 尝试基于外键关系生成连接条件时,有时会找到有多个关系。在这些情况下,SQL Anywhere 通过将外键的角色名与该外键引用的主键表的相关名相匹配,确定要使用的外键关系。

以下几节介绍 SQL Anywhere 如何为键连接生成连接条件。在描述键连接的操作的规则中对这些信息进行了总结。

相关名和角色名

相关名是在查询的 FROM 子句中使用的表或视图的名称—它的初始名称或者在 FROM 子句中定义的别名。

角色名是外键的名称。对于给定的外(子)表,角色名必须是唯一的。

如果您没有为外键指定角色名,则按如下所示指派角色名:

  • 如果没有任何外键的名称与主表名称相同,则将该主表名称指派为角色名。

  • 如果主表名称已由其它外键使用,则角色名将由该主表名称后接用零填充的三位数字组合而成(对于外表是唯一的)。

如果您不知道外键的角色名,则可以通过在 Sybase Central 的左窗格中展开数据库容器来查看。在左窗格中选择表,然后在右窗格中单击 [约束] 选项卡。表的外键列表会显示在右窗格中。

有关包括 SQL Anywhere 示例数据库中所有外键的角色名的图示,请参见示例数据库模式

生成连接条件

SQL Anywhere 查找其角色名与主键表的相关名相同的外键:

  • 如果恰好具有一个与连接中的表同名的外键,则 SQL Anywhere 使用它来生成连接条件。

  • 如果具有多个与表同名的外键,则连接是不明确的,并且将发出错误消息。

  • 如果没有与表同名的外键,则 SQL Anywhere 将查找任何外键关系,即使这些名称不匹配。如果有多个外键关系,则连接是不明确的,并且将发出错误消息。

示例 1

在 SQL Anywhere 示例数据库中,在表 Employees 和表 Departments 之间定义了两个外键关系:Employees 表中的外键 FK_DepartmentID_DepartmentID 引用 Departments 表;Departments 表中的外键 FK_DepartmentHeadID_EmployeeID 引用 Employees 表。

Employees 表和 Departments 表,显示有它们的外键关系。

以下查询是不明确的,因为该查询具有两个外键关系并且这两个外键关系都不具有与主键表名称相同的角色名。因此,尝试执行此查询将引起语法错误 SQLE_AMBIGUOUS_JOIN (-147)

SELECT Employees.Surname, Departments.DepartmentName
FROM Employees KEY JOIN Departments;
示例 2

此查询为 Departments 表指定相关名 FK_DepartmentID_DepartmentID,修改了示例 1 中的查询。现在,外键 FK_DepartmentID_DepartmentID 与其引用的表具有相同的名称,因此用它来定义连接条件。结果中包括所有雇员的姓氏以及他们就职的部门。

SELECT Employees.Surname, 
    FK_DepartmentID_DepartmentID.DepartmentName
FROM Employees KEY JOIN Departments 
    AS FK_DepartmentID_DepartmentID;

下面的查询是等效的。在此示例中,不必为 Departments 表创建别名。在此查询的 ON 子句中指定与上述语句生成的相同的连接条件:

SELECT Employees.Surname, Departments.DepartmentName
FROM Employees JOIN Departments
   ON Departments.DepartmentID = Employees.DepartmentID;
示例 3

如果想要列出所有担任部门领导的雇员,则应使用外键 FK_DepartmentHeadID_EmployeeID,并且应按如下所示重写示例 1。此查询通过为主键表 Employees 指定相关名 FK_DepartmentHeadID_EmployeeID,强制使用外键 FK_DepartmentHeadID_EmployeeID。

SELECT FK_DepartmentHeadID_EmployeeID.Surname, Departments.DepartmentName
FROM Employees AS FK_DepartmentHeadID_EmployeeID 
    KEY JOIN Departments;

下一个查询是等效的。在此查询的 ON 子句中指定与上述语句生成的相同的连接条件:

SELECT Employees.Surname, Departments.DepartmentName
FROM Employees JOIN Departments
   ON Departments.DepartmentHeadID = Employees.EmployeeID;
示例 4

如果外键角色名与主键表名相同,则不需要相关名。例如,可以为 Employees 表定义外键 Departments:

ALTER TABLE Employees 
   ADD FOREIGN KEY Departments (DepartmentID) 
   REFERENCES Departments (DepartmentID);

现在,此外键关系是在这两个表之间指定 KEY JOIN 时的缺省连接条件。如果定义外键 Departments,则下面的查询等效于示例 3。

SELECT Employees.Surname, Departments.DepartmentName
FROM Employees KEY JOIN Departments;
注意

如果您在 Interactive SQL 中尝试此示例,则应使用下面的语句撤消对 SQL Anywhere 示例数据库的更改:

ALTER TABLE Employees DROP FOREIGN KEY Departments;