使用重复表名称的原因是为了创建星形连接。在星形连接中,一个表或视图与若干其它表或视图相连接。
若要创建星形连接,应在 FROM 子句中多次使用同一个表名称、视图名称或相关名。这是对 ANSI/ISO SQL 标准的扩展。能够使用重复名并不添加任何附加功能,但这可以使某些查询写起来更加容易。
为使语法有意义,重复名必须位于不同的连接中。如果在同一连接中使用两次表名称或视图名称,则忽略第二个实例。例如,FROM A,A
和 FROM A CROSS JOIN A
均解释为 FROM A
。
在 SQL Anywhere 中,以下示例是有效的,其中 A、B 和 C 是表。在此示例中,表 A 的同一实例同时连接到 B 和 C。请注意,在星形连接中需要使用逗号分隔这些连接。在星形连接中使用逗号是星形连接语法所特有的。
SELECT * FROM A LEFT OUTER JOIN B ON A.x = B.x, A LEFT OUTER JOIN C ON A.y = C.y; |
下一个示例是等效的。
SELECT * FROM A LEFT OUTER JOIN B ON A.x = B.x, C RIGHT OUTER JOIN A ON A.y = C.y; |
这两个示例都等效于以下标准 ANSI/ISO 语法。(括号是可选的。)
SELECT * FROM (A LEFT OUTER JOIN B ON A.x = B.x) LEFT OUTER JOIN C ON A.y = C.y; |
在下一个示例中,将表 A 连接到三个表:B、C 和 D。
SELECT * FROM A JOIN B ON A.x = B.x, A JOIN C ON A.y = C.y, A JOIN D ON A.w = D.w; |
这等效于以下标准 ANSI/ISO 语法。(括号是可选的。)
SELECT * FROM ((A JOIN B ON A.x = B.x) JOIN C ON A.y = C.y) JOIN D ON A.w = D.w; |
遇到复杂连接时,画图会很有帮助。上面的示例可通过下图描述,该图示阐释表 B、C 和 D 通过表 A 连接。
创建给 Rollin Overbey 下订单的客户名称的列表。请注意,FROM 子句中的表 Employees 的任何列均未出现在结果中。所连接的任何列—例如 Customers.ID 或 Employees.EmployeeID—也未出现在结果中。不过,只有在 FROM 子句中使用 Employees 表才能实现该连接。
SELECT Customers.GivenName, Customers.Surname, SalesOrders.OrderDate FROM SalesOrders KEY JOIN Customers, SalesOrders KEY JOIN Employees WHERE Employees.GivenName = 'Rollin' AND Employees.Surname = 'Overbey' ORDER BY SalesOrders.OrderDate; |
GivenName | Surname | OrderDate |
---|---|---|
Tommie | Wooten | 2000-01-03 |
Michael | Agliori | 2000-01-08 |
Salton | Pepper | 2000-01-17 |
Tommie | Wooten | 2000-01-23 |
... | ... | ... |
以下是采用标准 ANSI/ISO 语法的等效语句:
SELECT Customers.GivenName, Customers.Surname, SalesOrders.OrderDate FROM SalesOrders JOIN Customers ON SalesOrders.CustomerID = Customers.ID JOIN Employees ON SalesOrders.SalesRepresentative = Employees.EmployeeID WHERE Employees.GivenName = 'Rollin' AND Employees.Surname = 'Overbey' ORDER BY SalesOrders.OrderDate; |
本示例回答的问题是:每位客户订购每种产品的数量是多少?谁是获得订单的销售人员的经理?
为回答这些问题,应首先列出您需要检索的信息。在此例子中,需要检索的信息是产品、数量、客户名称和经理姓名。接下来,列出保存这些信息的表。它们是 Products、SalesOrderItems、Customers 和 Employees。查看 SQL Anywhere 示例数据库的结构时(请参见示例数据库模式),您将注意到,这些表全部通过 SalesOrders 表进行关联。您可以为 SalesOrders 表创建星形连接,以检索其它表中的信息。
此外,您还需要创建自连接,以便获取经理姓名,因为 Employees 表包含经理的 ID 号和所有雇员的姓名,但没有仅列出经理姓名的列。有关详细信息,请参见自连接。
以下语句围绕 SalesOrders 表创建星形连接。这些连接全都是外连接,因此结果集将包括所有客户。有些客户没有下订单,因此对应这些客户的其它值为空。结果集中的列是客户、产品、订购的数量以及销售人员的经理的姓名。
SELECT Customers.GivenName, Products.Name, SUM(SalesOrderItems.Quantity), m.GivenName FROM SalesOrders KEY RIGHT OUTER JOIN Customers, SalesOrders KEY LEFT OUTER JOIN SalesOrderItems KEY LEFT OUTER JOIN Products, SalesOrders KEY LEFT OUTER JOIN Employees AS e LEFT OUTER JOIN Employees AS m ON (e.ManagerID = m.EmployeeID) WHERE Customers.State = 'CA' GROUP BY Customers.GivenName, Products.Name, m.GivenName ORDER BY SUM(SalesOrderItems.Quantity) DESC, Customers.GivenName; |
GivenName | Name | SUM(SalesOrderItems.Quantity) | GivenName |
---|---|---|---|
Sheng | Baseball Cap | 240 | Moira |
Laura | Tee Shirt | 192 | Moira |
Moe | Tee Shirt | 192 | Moira |
Leilani | Sweatshirt | 132 | Moira |
... | ... | ... | ... |
以下是此星形连接中各表的图示。箭头指示这些外连接的方向(左或右)。正如您所看到的,整个客户列表是贯穿所有连接来维护的。
以下标准 ANSI/ISO 语法等效于示例 2 中的星形连接。
SELECT Customers.GivenName, Products.Name, SUM(SalesOrderItems.Quantity), m.GivenName FROM SalesOrders LEFT OUTER JOIN SalesOrderItems ON SalesOrders.ID = SalesOrderItems.ID LEFT OUTER JOIN Products ON SalesOrderItems.ProductID = Products.ID LEFT OUTER JOIN Employees as e ON SalesOrders.SalesRepresentative = e.EmployeeID LEFT OUTER JOIN Employees as m ON e.ManagerID = m.EmployeeID RIGHT OUTER JOIN Customers ON SalesOrders.CustomerID = Customers.ID WHERE Customers.State = 'CA' GROUP BY Customers.GivenName, Products.Name, m.GivenName ORDER BY SUM(SalesOrderItems.Quantity) DESC, Customers.GivenName; |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |