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 都会考虑在查询和视图的 FROM 子句中的表对,并为所有表对的集合生成一个连接条件,而不管视图的 FROM 子句中是包含逗号还是连接关键字。

  • SQL Anywhere 基于其角色名与视图或派生表的相关名同名的外键连接表。

  • 在键连接中包括视图或派生表时,视图或派生表定义中不能包含 UNION、INTERSECT、EXCEPT、ORDER BY、DISTINCT、GROUP BY、集合函数、窗口函数、TOP、FIRST、START AT 或 FOR XML。如果它包含以上任何一项,则返回错误。此外,不能将派生表定义为递归表表达式。

    派生表的工作原理与视图大体相同。唯一差别就是:表的定义包括在语句中,而不是引用预定义的视图。

    有关递归表表达式的信息,请参见递归公用表表达式RecursiveTable 算法 (RT)

示例 1

例如,在以下语句中,View1 是一个视图。

SELECT *
FROM View1 KEY JOIN B;

View1 的定义可以是以下任何一个,结果得到相同的连接条件与 B 连接。(结果集不同,但连接条件相同。)

SELECT *
FROM C CROSS JOIN D;

或者

SELECT *
FROM C,D;

或者

SELECT *
FROM C JOIN D ON (C.x = D.y);

在每种情况下,在为 View1 和 B 的键连接生成连接条件时,SQL Anywhere 会考虑表对 C-B 和 D-B,并生成一个连接条件。它基于表的表达式的键连接中描述的适用于多个外键关系的规则生成连接条件,只不过它会查找与视图(而不是在视图中引用的表)的相关名同名的外键。

使用以上任一视图定义时,您都可以按如下所述解释 View1 KEY JOIN B 的处理过程:

SQL Anywhere 通过考虑表对 C-B 和 D-B 来生成单个连接条件。它根据以下有多个外键关系时确定键连接的规则来生成该连接条件:

  • 首先,它查找 C-B 和 D-B 是否存在其角色名与视图的相关名同名的一个外键。如果正好只有一个外键满足此条件,则使用此外键。如果有多个角色名与视图的相关名同名的外键,则认为该连接是不明确的,并且发出错误消息。

  • 如果没有任何外键与视图的相关名同名,则 SQL Anywhere 将查找这些表间的任何外键关系。如果只有一个外键关系,则使用此外键关系。如果有多个外键关系,则认为该连接是不明确的,并会发出错误消息。

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

假设此生成的连接条件是 B.y = D.z。现在可以展开原始连接。例如,以下两个语句是等效的:

SELECT *
FROM View1 KEY JOIN B;

SELECT *
FROM View1 JOIN B ON B.y = View1.z;

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

示例 2

以下视图包含与每一部门的经理有关的所有雇员信息。

CREATE VIEW V AS
SELECT Departments.DepartmentName, Employees.*
FROM Employees JOIN Departments
  ON Employees.EmployeeID = Departments.DepartmentHeadID;

以下查询将该视图连接到一个表表达式。

SELECT *
FROM V KEY JOIN ( SalesOrders, 
   Departments FK_DepartmentID_DepartmentID );

以下查询等同于上一查询:

SELECT *
FROM V JOIN ( SalesOrders, 
   Departments FK_DepartmentID_DepartmentID )
ON ( V.EmployeeID = SalesOrders.SalesRepresentative
AND V.DepartmentID = 
    FK_DepartmentID_DepartmentID.DepartmentID );