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 为表表达式列表中的每个表生成一个连接条件。

例如,以下语句是一个表表达式列表与一个不包含逗号的表表达式的键连接。本示例为表 A 和表表达式 C NATURAL JOIN D 以及表 B 和表表达式 C NATURAL JOIN D 生成一个连接条件。

SELECT *
FROM (A,B) KEY JOIN (C NATURAL JOIN D);

(A,B) 是表表达式列表,C NATURAL JOIN D 是表表达式。因此,SQL Anywhere 必须生成两个连接条件:它为 A-C 和 A-D 对生成一个连接条件,为 B-C 和 B-D 对生成第二个连接条件。它根据存在多个外键关系时的键连接规则生成连接条件:

  • 对于每组表对,SQL Anywhere 查找其角色名与其中一个主键表的相关名同名的外键。如果正好只有一个外键满足此条件,则使用此外键。如果有多个,则认为该连接是不明确的,并且发出错误消息。

  • 对于每组表对,如果不存在其角色名与主键表的相关名同名的外键,则 SQL Anywhere 查找这些表间的任何外键关系。如果恰好有一个外键关系,则连接条件使用此关系。如果有多个,则认为该连接是不明确的,并且发出错误消息。

  • 对于每组对,如果没有任何外键关系,则发出错误消息。

  • 如果 SQL Anywhere 能够为每一组表对确定恰好一个连接条件,则它将使用关键字 AND 来组合这些连接条件。

示例 1

考虑以下 5 个表的连接:

((A,B) JOIN (C NATURAL JOIN D) ON A.x = D.y) KEY JOIN E

在此示例中,SQL Anywhere 通过在 (A,B) 和 E 之间或在 C NATURAL JOIN D 和 E 之间生成条件的方式来为与 E 的键连接生成连接条件。不包含逗号的表的表达式的键连接中说明了这一情况。

如果 SQL Anywhere 在 (A,B) 和 E 之间生成连接条件,则它需要创建两个连接条件,为 A-E 创建一个,为 B-E 创建另一个。它必须查找每个表对中有效的外键关系。表的表达式列表的键连接中说明了这一情况。

如果 SQL Anywhere 在 C NATURAL JOIN D 和 E 之间创建连接条件,则它将只创建一个连接条件,因此必须只在 C-E 和 D-E 对中找到一个外键关系。不包含逗号的表的表达式的键连接中说明了这一情况。

示例 2

以下是表表达式和表表达式列表的键连接的示例。该示例提供既是销售代表也是经理的雇员的姓名和部门。

SELECT DISTINCT Employees.Surname, 
        FK_DepartmentID_DepartmentID.DepartmentName
FROM ( SalesOrders, Departments 
        AS FK_DepartmentID_DepartmentID )
    KEY JOIN ( Employees JOIN Departments AS d
        ON Employees.EmployeeID = d.DepartmentHeadID );

SQL Anywhere 生成两个连接条件:

  • 表对 SalesOrders/Employees 和 SalesOrders/d 之间正好有一个外键关系: SalesOrders.SalesRepresentative = Employees.EmployeeID.

  • 表对 FK_DepartmentID_DepartmentID/Employees 和 FK_DepartmentID_DepartmentID/d 之间正好有一个外键关系:FK_DepartmentID_DepartmentID.DepartmentID = Employees.DepartmentID

此示例等效于下面的语句。在以下版本中,不必创建相关名 Departments AS FK_DepartmentID_DepartmentID,因为只有在说明应使用两个外键中的哪一个来连接 Employees 和 Departments 时才需要相关名。

SELECT DISTINCT Employees.Surname, 
   Departments.DepartmentName
FROM ( SalesOrders, Departments )
    JOIN ( Employees JOIN Departments AS d
       ON Employees.EmployeeID = d.DepartmentHeadID )
    ON SalesOrders.SalesRepresentative = Employees.EmployeeID
       AND Departments.DepartmentID = Employees.DepartmentID;