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 的用法 » 查询和修改数据 » 对查询结果进行汇总、分组和排序 » 使用集合函数汇总查询结果

 

在哪些地方可以使用集合函数

可以在选择列表中使用集合函数(如前面的示例中所示),也可以在包括 GROUP BY 子句的选择语句的 HAVING 子句中使用集合函数。请参见HAVING 子句:选择数据组

不能在 WHERE 子句或 JOIN 条件中使用集合函数。不过,选择列表中有集合函数的 SELECT 语句通常包括 WHERE 子句,该子句会对应用集合的行加以限制。

如果 SELECT 语句包括 WHERE 子句,而不包括 GROUP BY 子句,则集合函数会为 WHERE 子句指定的行的子集生成一个值。

只要是在不包括 GROUP BY 子句的 SELECT 语句中使用集合函数,集合函数就会生成一个值。无论集合函数是作用于表中的所有行,还是 where 子句定义的行的子集,都是如此。

您可以在同一选择列表中使用多个集合函数,并且可以在一个 SELECT 语句中生成多个标量集合。

集合函数和外部引用

SQL Anywhere 遵循 SQL/2003 标准,明确集合函数在子查询中出现时的用法。这些更改将影响为该软件的以前版本编写的语句的行为:以前正确的查询现在可能产生错误消息,结果集也可能发生变化。

当集合函数出现在子查询中并且集合函数引用的列是外部引用时,整个集合函数本身现在会被视为外部引用。这意味着集合函数现在将在外部块而非子查询中进行计算,并会成为子查询内的常量。

在子查询中使用外部引用集合函数时受到以下限制:

  • 外部引用集合函数只能出现在位于 SELECT 列表或 HAVING 子句中的子查询中,并且这些子句必须位于紧接的外部块中。

  • 外部引用集合函数只能包含一个外部列引用。

  • 本地列引用和外部列引用不能在同一集合函数中混用。

通过重写集合函数来使其仅包括本地引用,可以规避与新标准有关的某些问题。例如,子查询 (SELECT MAX(S.y + R.y) FROM S) 同时包含本地列引用 (S.y) 和外部列引用 (R.y),现在这是非法的。可以将其重写为 (SELECT MAX(S.y) + R.y FROM S)。在改写的内容中,集合函数只具有本地列引用。当外部引用集合函数出现在 SELECT 或 HAVING 以外的子句中时,可以进行同一类型的改写。

示例

以下查询在 Adaptive Server Anywhere 第 7 版中生成以下结果。

SELECT Name, 
      ( SELECT SUM( p.Quantity )
           FROM SalesOrderItems )
   FROM Products p;
Name SUM(p.Quantity)
Tee shirt 30,716
Tee shirt 59,238

在更高版本中,同一查询会生成错误消息 [SQL Anywhere 错误 -149:对 'name' 的函数或列引用还必须出现在 GROUP BY 中]。该语句不再有效的原因在于:外部引用集合函数 [sum(p.Quantity)] 现在是在外部块中进行计算。在更高版本中,该查询在语义上等效于以下语句(不同的是 Z 不作为结果集的一部分出现):

SELECT Name,
       SUM( p.Quantity ) AS Z,
       ( SELECT Z 
            FROM SalesOrderItems )
   FROM Products p;

由于现在是由外部块来计算集合函数,因此外部块被视作分组查询,而列名必须出现在 GROUP BY 子句中,才能在 SELECT 列表中出现。