远程Sybase数据库技术支持,联系手机:13811580958,QQ:289965371!

 

随着Sybase被完全整合到SAP下,Sybase原来的支持网站被SAP Support Portal取代。
只有购买了SAP服务的用户才能使用账号登录SAP Support Portal进行介质下载、补丁升级、报Incident等。
目前,原Sybase所有产品(包括:Adaptive Server Enterprise、Sybase IQ、Replication Server、PowerDesigner等)的官方手册仍然可以从http://infocenter.sybase.com/help/index.jsp进行浏览或下载。暂不清楚该网站http://infocenter.sybase.com/help/index.jsp何时会被完全迁移到SAP Support上!
Sybase官方手册英文版有html和pdf两种格式,而中文版手册只有pdf一种格式。为了国内Sybase用户更方便、快捷地搜索Sybase常见产品的官方手册内容,特将中文版Sybase官方手册转为html格式!
Sybase产品官方手册中文版的html格式所有内容的版权归SAP公司所有!本博客站长是Sybase数据库的铁杆粉丝!

如有Sybase数据库技术问题需要咨询,请联系我!

  QQ :289965371 点击这里给我发消息
  Email:

以下官方手册为ASE 15.7 ESD#2中文版:

  1. 新增功能公告 适用于 Windows、Linux 和 UNIX 的 Open Server 15.7 和 SDK 15.7
  2. 新增功能摘要
  3. 新增功能指南
  4. ASE 15.7 发行公告
  5. 配置指南(windows)
  6. 安装指南(windows)
  7. 参考手册:构件块
  8. 参考手册:命令
  9. 参考手册:过程
  10. 参考手册:表
  11. Transact-SQL® 用户指南
  12. 系统管理指南,卷 1
  13. 系统管理指南,卷 2
  14. 性能和调优系列:基础知识
  15. 性能和调优系列:锁定和并发控制
  16. 性能和调优系列:监控表
  17. 性能和调优系列:物理数据库调优
  18. 性能和调优系列:查询处理和抽象计划
  19. 性能和调优系列:使用 sp_sysmon 监控 Adaptive Server
  20. 性能和调优系列:利用统计分析改进性能
  21. 程序员参考 jConnect for JDBC 7.0.7
  22. Adaptive Server Enterprise 中的 Java
  23. 组件集成服务用户指南
  24. Ribo 用户指南
  25. 内存数据库用户指南
  26. Sybase Control Center for Adaptive Server® Enterprise
  27. 安全性管理指南
  28. 实用程序指南

 


< 上一个 | 内容 | 下一步 >

group by having 子句

说明 select 语句中使用,用于将表划分为组,并仅返回与 having 子句中的 条件匹配的组。group by 通常与集合一起使用,以指定如何对 select 查询 的未集合的列进行分组。 having 子句应用于这些组。

语法 Start of select statement

[group by [all] aggregate_free_expression

[, aggregate_free_expression]...] [having search_conditions]

End of select statement

参数 group by

指定要将表划分为哪些组,并且如果集合函数包括在选择列表中,则 为每个组生成一个摘要值。这些摘要值在结果中作为列出现,每一列 对应一个组。在 having 子句中可以引用这些摘要列。

可在 group by 前面的选择列表中使用 avgcountcount_bigmaxmin sum 集合函数 (该表达式通常为列名)。请参见 《参考手册: 构件块》的 2 章 “ Transact-SQL 函数”

可以按任何列的组合对表分组 即组可互相嵌套,如示例 2 所示。

all


是一个 Transact-SQL 扩展,它在结果中包含所有组,即使那些由

where 子句所排除的组也被包括进来。例如:

select type, avg (price) from titles

where advance > 7000 group by all type


type

----------------- ---------- UNDECIDED NULL

business 2.99

mod_cook 2.99

popular_comp 20.00

psychology NULL

trad_cook 14.99

(6 rows affected)

集合列中的 “NULL”指示了将由 where 子句排除的组。 having 子句 否定 all 的含义。


aggregate_free_expression

是不包含集合的表达式。 Transact-SQL 扩展允许按不包含集合的表达 式和按列名分组。

不能按列标题或别名分组。下面的示例是正确的:

select Price=avg (price), Pay=avg (advance),

Total=price * $1.15 from titles

group by price * $1.15

having

设置 group by 子句的条件,与 where 设置 select 子句的条件的方法相似。

having 搜索条件可包含集合表达式;否则, having 搜索条件与 where

搜索条件相同。下面是一个带集合的 having 子句的示例:

select pub_id, total = sum (total_sales) from titles

where total_sales is not null group by pub_id

having count(*) > 5

Adaptive Server 优化查询时,它将对 where having 子句中的搜索 条件求值,以确定哪些条件是可以用于选择最佳索引和查询计划的搜 索参数 (SARG)。所有搜索条件都用来限定行。有关搜索参数的详细 信息,请参见 《性能和调优指南:优化程序和抽象计划》。

示例 示例 1 计算每类书籍的平均预付款以及总销售额:

select type, avg(advance), sum(total_sales) from titles

group by type

示例 2 将结果按类型分组,然后按每种类型中的 pub_id 分组:

select type, pub_id, avg (advance), sum (total_sales) from titles

group by type, pub_id

示例 3 计算所有组的结果,但仅显示类型以 “p”开头的组:

select type, avg (price) from titles

group by type

having type like 'p%'

示例 4 计算所有组的结果,但仅显示与 having 子句中的多个条件匹配的 组:

select pub_id, sum(advance), avg(price)


from titles group by pub_id

having sum (advance) > $15000 and avg (price) < $10

and pub_id > "0700"

示例 5 连接 titles publishers 表后计算每个组 (出版社)的销售额:

select p.pub_id, sum (t.total_sales) from publishers p, titles t

where p.pub_id = t.pub_id group by p.pub_id

示例 6 显示预付款高于 $1000,并且价格高于所有书籍平均价格的书籍 的名称:

select title_id, advance, price from titles

where advance > 1000 having price > avg (price)

用法 可在 group by 后使用列名或任何表达式 (列标题或别名除外)。可 以使用 group by 计算结果或显示不出现在选择列表中的列或表达式

438 页的 “ group by having Transact-SQL 扩展”中介绍的

Transact-SQL 扩展)。

未对 group by 列 (或表达式)的最大数量明确进行限制。 group by

结果的唯一限制是 group by 列加上集合结果的宽度不超过 64K

group by 列中的 NULL 值将放在单个组中。

不能在 group by having 子句中指定 textunitext image 列。

不能在可更新游标的 select 语句中使用 group by 子句。

集合函数仅能在选择列表或 having 子句中使用。它们不能用于

where group by 子句中。

集合函数有两种类型。应用于 表中所有限定行 的集合 (每个函数 为整个表产生一个值)称为标量集合。没有 group by 子句的选择列 表中的集合函数应用于整个表;这是一个标量集合的示例。

应用于指定列或表达式中的一组行 的集合 (每个函数为每个组产 生一个值)称为矢量集合。对于这两种类型的集合,集合运算的结 果显示为 having 子句可以引用的一个新列。

可将矢量集合嵌套在标量集合中。有关详细信息,请参见 《参考手 册:构件块》的2 章 “Transact-SQL 函数”


group by 使用优化程序

Adaptive Server 15.0 版中,有两种可能的算法 (作为运算符实现)用 于执行 group byGroupHashing GroupSorted。优化程序根据相应的因 素选择要使用哪种运算符,例如这些运算符对输入数据流的要求。

GroupSorted 运算符要求要进行集合的输入行已经在组中按列排序。由 于输入行必须排序,因此优化程序使用以下任一种方式:

使用 order by 列的索引从源表中读取行,并且 group by 列的最大宽 度受到索引键最大宽度的限制,这取决于数据库页大小。

使用 Asort 运算符在 GroupSorted 运算符处理 group by 列中的行之 前,对这些行进行排序。 group by 列和要进行集合的列必须适合放 入工作表,因此 group by 列的最大宽度限制为数据库页上的最大行 大小减去要进行集合的列的宽度。 group by 列的最大宽度受到数据 库页大小的限制。

如果没有对 group by 列进行排序,或者超出了 GroupSorted 运算符的行 大小限制,则优化程序使用 GroupHashing 运算符。 GroupHashing 运算 符将一个散列函数应用于 group by 列的值,以便能够将具有相同 group by 列值的行放入相同的散列桶中。一旦输入行已全部散列到桶中,则 桶中的行将进行集合以生成 group by 结果。GroupHashing 运算符的唯一 限制是 group by 列和集合结果的总的行大小不能超过 64K。对于 group by 列的数量以及集合操作的数量没有限制,只对总的行宽度有限制。

使用集合的 group by having 查询的工作方式

where 子句排除不符合其搜索条件的行;其功能在分组查询或非分组查 询中都一样。

对于 group by 表达式中的每个唯一值, group by 子句都会将剩余的行集 中到一组中。省略 group by 会为整个表创建单个组。

在选择列表中指定的集合函数计算每组的汇总值。对于标量集合来说, 表只有一个值。矢量集合为不同的组计算值。

having 子句将不满足其搜索条件的组从结果中排除。尽管 having 子句仅 测试行,但 group by 子句的存在与不存在会令其看起来像是在对组或行 进行操作:

当查询中包含 group by 时,having 会排除结果组行。这就是 having 好 像在对组进行操作的原因。

当查询不包含 group by 时, having 排除 (只有一个组的)表中的结 果行。这就是 having 好像在对行进行操作的原因 (其结果与 where 子句的结果相似)。


标准 group by having 查询

示例部分中的所有 group by having 查询遵循 SQL 标准,该标准规定使 用 group byhaving 和矢量集合函数的查询使用下列规则为每组生成一 行和一个摘要值:

选择列表中的列必须也出现在 group by 表达式中,或者必须是集合 函数的参数。

group by 表达式只能包含选择列表中出现的列名。不过,选择列表 中仅作为集合函数的参数使用的列不适用此限定。

having 表达式中的列必须是单值的 (例如集合的参数),而且它们 必须出现在选择列表或 group by 子句中。使用选择列表集合和 having 子句的查询必须 包含 group by 子句。如果在未使用选择列表 集合的查询中省略 group by,则所有未被 where 子句排除的行将被视 为单个组。

在非分组查询中,“用 where 排除行”的原则是非常简单直接的。在分 组查询中,此原则扩展为 “使用 where group by 之前排除行,使用 having 从显示的结果中排除行”。

SQL 标准允许连接两个或更多表的查询使用 group by having,只要它 们遵循上述原则。指定连接或其它复杂查询时,请使用 group by having 的标准语法,除非您完全理解 Transact-SQL 扩展对这两个子句的 影响。

为了帮助您避免有关扩展的问题, Adaptive Server set 命令提供了 fipsflagger 选项,这样每次查询中出现 Transact-SQL 扩展时都会发出一 个非致命警告。有关详细信息,请参见 set

group by having Transact-SQL 扩展

对标准 SQL Transact-SQL 扩展使得数据的显示更加灵活,因为在扩 展中允许引用未在创建组或摘要计算时使用的列和表达式:

包含集合的选择列表可以包括既不是集合函数的参数,也不包括在 group by 子句的扩展 列。扩展列影响最终结果的显示,因为显示了 附加的行。

group by 子句可包含未列于选择列表中的列或表达式。

group by all 子句显示所有组,甚至是那些由 where 子句从计算中排除 的组。请参见 “参数”一节中关键字 all 的示例。

having 子句可以包含未出现在选择列表以及 group by 子句中的列或 表达式。


Transact-SQL 扩展将行或列添加到显示中时,或省略 group by 时,查询 结果可能难以理解。以下示例可帮助您理解 Transact-SQL 扩展对查询结 果的影响。

以下示例说明了使用标准 group by having 子句的查询和使用

Transact-SQL 扩展的查询之间的区别:

1 标准分组查询示例:

select type, avg (price) from titles

----------------------

----------

UNDECIDED

NULL

business

13.73

mod_cook

11.49

popular_comp

21.48

psychology

13.50

trad_cook

15.96

----------------------

----------

UNDECIDED

NULL

business

13.73

mod_cook

11.49

popular_comp

21.48

psychology

13.50

trad_cook

15.96

group by type type


(6 rows affected)

2 Transact-SQL 扩展列 price (在选择列表中,但不是集合,也不在 group by 子句中)导致所有限定行都显示在每个限定组中,即使标准 group by 子句仅为每个组生成了一个行。 group by 仍影响矢量集合, 后者计算显示在每个组的每一行上的每组平均价格 (与为示例 a 计 算的值相同):

select type, price, avg (price) from titles

group by type

type price

------------ ---------------- --------------

business 19.99 13.73

business 11.95 13.73

business 2.99 13.73

business 19.99 13.73

mod_cook 19.99 11.49

mod_cook 2.99 11.49

UNDECIDED NULL NULL

popular_comp 22.95 21.48

popular_comp 20.00 21.48

popular_comp NULL 21.48

psychology 21.59 13.50

psychology 10.95 13.50

psychology 7.00 13.50


psychology

19.99

13.50

psychology

7.99

13.50

trad_cook

20.95

15.96

trad_cook

11.95

15.96

trad_cook 14.99


(18 rows affected)

15.96

3 处理 Transact-SQL 扩展列的方式看起来就像一个查询忽略了 where 子句。此查询仅计算满足 where 子句的条件的行的平均价格,但它 也显示与 where 子句中的条件不匹配的行。

Adaptive Server 首先使用 where 子句创建一个仅包含类型和集合值 的工作表。此工作表通过分组列 type 连接回 titles 表,以在结果中包 括 price 列,但连接中没有 使用 where 子句。

titles 中唯一不会在结果中出现的行是一个 type 为 “UNDECIDED”、价格为 NULL 的单独的行,也就是不会在工作 表中为其输出结果的一行。如果还想在显示的结果中去除价格低于

$10.00 的行,就必须添加一个重复 where 子句的 having 子句,如示 例 4 所示:

select type, price, avg (price) from titles

where price > 10.00 group by type

type price

------------ ---------------- --------------

business 19.99 17.31

business 11.95 17.31

business 2.99 17.31

business 19.99 17.31

mod_cook 19.99 19.99

mod_cook 2.99 19.99

popular_comp 22.95 21.48

popular_comp 20.00 21.48

popular_comp NULL 21.48

psychology 21.59 17.51

psychology 10.95 17.51

psychology 7.00 17.51

psychology 19.99 17.51

psychology 7.99 17.51

trad_cook 20.95 15.96

trad_cook 11.95 15.96

trad_cook 14.99 15.96

(17 rows affected)


4 如果要在 having 子句中指定附加条件 (例如集合),则还要包括 where 子句中指定的所有条件。Adaptive Server 看起来会忽略 having 子句中所缺少的所有 where 子句条件:

select type, price, avg (price) from titles

where price > 10.00 group by type

----------- ---------------- --------------

business 19.99

17.31

business 11.95

17.31

business 19.99

17.31

mod_cook 19.99

19.99

popular_comp 22.95

21.48

popular_comp 20.00

21.48

psychology 21.59

17.51

psychology 10.95

17.51

psychology 19.99

17.51

trad_cook 20.95

15.96

trad_cook 11.95

15.96

trad_cook 14.99

15.96

----------- ---------------- --------------

business 19.99

17.31

business 11.95

17.31

business 19.99

17.31

mod_cook 19.99

19.99

popular_comp 22.95

21.48

popular_comp 20.00

21.48

psychology 21.59

17.51

psychology 10.95

17.51

psychology 19.99

17.51

trad_cook 20.95

15.96

trad_cook 11.95

15.96

trad_cook 14.99

15.96

having price > 10.00 type price


(12 rows affected)

5 这是一个使用两个表之间的连接的标准分组查询的示例。它根据 pub_id 分组,然后根据每个出版社 ID type 分组,来计算每行的矢 量集合:

select p.pub_id, t.type, sum (t.total_sales) from publishers p, titles t

where p.pub_id = t.pub_id group by p.pub_id, t.type

pub_id type

--- --- ----- ------- - -------

0736

business

18722

0736

psychology

9564

0877

UNDECIDED

NULL

0877

mod_cook

24278

0877

psychology

375

0877

trad_cook

19566

1389

business

12066

1389

popular_comp

12875

(8 rows affected)


看起来好像只需要为 pub_id type 列指定 group by 即可生成上述结 果,下面按如下所示添加扩展列:

select p.pub_id, p.pub_name, t.type, sum (t.total_sales)

from publishers p, titles t where p.pub_id = t.pub_id group by p.pub_id, t.type

不过,上面的查询的结果与本示例中第一个查询的结果有相当大的 差别。在连接这两个表以确定工作表中的矢量集合后, Adaptive Server 会将工作表与该扩展列的表 (publishers) 连接,从而生成最终 结果。不同表中的每个扩展列都会调用一个附加的连接。

如您所见,在连接表的查询中使用扩展列扩展很容易产生难以理解 的结果。多数情况下,请在查询中使用标准 group by 来连接表。

6 此示例使用对 group by Transact-SQL 扩展来包含未出现在选择列 表中的列。 pub_id type 列用于对矢量集合的结果进行分组。不 过,最终结果不包含每个出版社中的类型。在这种情况下,您可能 只需要知道每个出版社销售多少种书籍:

select p.pub_id, sum (t.total_sales) from publishers p, titles t

where p.pub_id = t.pub_id group by p.pub_id, t.type

pub_id

- -----

0736

--- -----

18722

0736

9564

0877

NULL

0877

24278

0877

375

0877

19566

1389

12066

1389

12875

(8 rows affected)

7 此示例组合了两种 Transact-SQL 扩展效果。首先,它在选择列表中 包含集合时省略 group by 子句。接着,它包含了一个扩展列。由于 省略了 group by 子句:

整个表成为了一个组。标量集合计算得到三个限定的行。

pub_id 成为 Transact-SQL 扩展列,因为它未出现在 group by 子句 中。没有 having 子句,因此会显示组中的所有行。


select pub_id, count (pub_id) from publishers

pub_id

----------

---------

0736

3

0877

3

1389

3

(3 rows affected)

8 where 子句从一个组中排除 pub_id 等于或大于 1000 的出版社,因此 标量集合计算得到两个限定的行。扩展列 pub_id 显示 publishers 表中 的所有限定行:

select pub_id, count (pub_id) from publishers

where pub_id < "1000"

pub_id

-------------- ----------- 0736 2

0877 2

1389 2


(3 rows affected)

9 此示例说明了不使用 group by 子句时 having 子句的效果。

整个表被视为一个组。没有使用 where 子句排除行,因此将对 组 (表)中的所有行计数。

此单个组表中的行通过 having 子句进行测试。

这些组合的效果显示了两个限定的行。

select pub_id, count (pub_id) from publishers

having pub_id < "1000"

pub_id

-------------- --------- 0736 3

0877 3

(2 rows affected)

10 此示例使用 having 的扩展,以允许使用不在选择列表和 group by 子 句中的列或表达式。它确定每一书籍类型的平均价格,但会将那些 总销售额未超过 $10,000 的类型排除在外,即使 sum 集合不出现在 结果中也是如此。


select type, avg (price) from titles

group by type

having sum (total_sales) > 10000

type

- ---------- - ------- ---

business 13.73

mod_cook 11.49

popular_comp 21.48

trad_cook 15.96


(4 rows affected)

group by having 及排序顺序

如果服务器的排序顺序不区分大小写, group by 将忽略分组列的大小 写。例如,在不区分大小写的服务器上存在以下数据:

select lname, amount from groupdemo

lname amount

---------- ------------------

Smith 10.00

smith 5.00

SMITH 7.00

Levi 9.00

Lé vi 20.00


grouping by lname 产生如下结果:

select lname, sum (amount) from groupdemo


lname

---------- ----------------

Levi 9.00

Lé vi 20.00

Smith 22.00


相同的查询在不区分大小写和变音的服务器上产生以下结果:

lname

---------- ------------------

Levi 29.00

Smith 22.00


标准 符合 ANSI SQL 的级别符合初级标准。

select 列表中使用不在 group by 列表中且不包含集合函数的列是一种

Transact-SQL 扩展。

使用 all 关键字是一种 Transact-SQL 扩展。

另请参见 命令 compute clause, declare, select, where 子句 .

文档 《参考手册:构件块》的2 章 “Transact-SQL 函数” .




--------------------------------------华丽的分割线-------------------------------------------------------------------------
之前就已经研发成功了能够从Sybase SQL Anywhere的DB文件中恢复数据的工具:ReadASADB。
此工具支持ASA v5.0,v6.0,v7.0,v8.0,v9.0,v10.0,v11.0,v12.0等版本。
恢复Sybase SQL Anywhere的工具在国内应该算首创。

ReadASADB功能
能够从损坏的SQL Anywhere数据文件(.db)和UltraLite数据文件(.udb)上提取数据的非常规恢复工具

  1. 适用于所有的SQL Anywhere版本    包括:5.x,6.x,7.x,8.x,9.x,10.x,11.x,12.x
  2. 适用于所有的UltraLite版本
  3. 能够恢复出来表结构和数据
  4. 能够恢复自定义数据类型
  5. 能够恢复存储过程等对象的语法
  6. 能够导出到目标数据库
  7. 能够导出到SQL文件并生成导入脚本
  8. 支持多种字符集  包括:cp850、cp936、gb18030、utf8等
  9. 能够恢复未加密或者简单加密类型的数据
  10. 简单易用
  11. 限制:不支持AES加密的数据文件
请参考:研发成功了从Sybase SQL Anywhere的DB文件上恢复数据的工具
            SQL Anywhere数据库非常规恢复工具ReadASADB使用介绍

ReadASADB适用场景

各种误操作:

  1. 误截断表(truncate table)
  2. 误删除表(drop table)
  3. 错误的where条件误删数据
  4. 误删除db或log文件
  5. 误删除表中的字段

本工具的应用场景:

1.因为物理磁盘故障、操作系统、系统软件方面或者掉电等等原因导致的Sybase SQL Anywhere数据库无法打开的情况;
2.误操作,包括truncate table,drop table,不正确的where条件导致的误删除等;
Sybase SQL Anywhere无法打开时,比较常见的错误是:Assertion failed。
如:
1、Internal database error *** ERROR *** Assertion failed:201819 (8.0.1.2600) Checkpoint log: invalid bitmap page -- transaction rolled back
2、Internal database error *** ERROR *** Assertion failed:201819 (8.0.1.2600) Page number on page does not match page requested -- transaction rolled back
3、Internal database error *** ERROR *** Assertion failed:200502 (9.0.2.2451) Checksum failure on page 23 -- transaction rolled back
4、File is shorter than expected
5、Internal database error *** ERROR *** Assertion failed: 201116 Invalid free list index page found while processing checkpoint log -- transaction rolled back
6、*** ERROR *** Assertion failed: 51901 Page for requested record not a table page or record not present on page等等。
+-------------------------------------华丽的分割线-------------------------------------------------------------------------