返回首页

gbase数据、南大通用产品文档:GBase8sGROUP BY 子句

更新日期:2024年09月11日

GROUP BY 子句将表分为几组。此子句通常与为每个这样的组生成总结值的聚集函数组
合。
编写 SELECT 语句中的某些示例显示了应用于整个表的聚集函数的用法。
本章说明应
用于行组的聚集函数。
使用不带聚集的 GROUP BY 子句与在 SELECT 子句中使用 DISTINCT(或 UNIQUE)
关键字很相似。下列查询在选择特定列中描述。
图: 查询
SELECT DISTINCT customer_num FROM orders;
还可以按以下查询编写此语句。
图: 查询
SELECT customer_num FROM orders
GROUP BY customer_num;

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 114 -

图 1和图 2返回下列行。
图: 查询结果
customer_num

101
104
106
110

124
126
127
GROUP BY 子句将行收集到组中,因此每一组中的每一行具有相同的客户号。在没有选择
任何其它列的情况下,结束是唯一 customer_num 值的列表。
GROUP BY 子句的功能在将它与聚集函数配合使用时更明显。
下列查询检索每个订单的商品数和所有商品的总价。
图: 查询
SELECT order_num, COUNT (*) number, SUM (total_price) price
FROM items
GROUP BY order_num;
GROUP BY 子句导致 items 表的行数被收集为组,每个组由具有相同 order_num 值的行组
成(即,将每个订单的商品收集在一起)。在数据库服务器构成组之后,就在每个组中应
用聚集行数 COUNT 和 SUM 。
图 4对每一组返回每一行。它还使用标号来为 COUNT 和 SUM 表达式的结果提供名称,
如下所示。
图: 查询结果
order_num number price

1001 1 $250.00
1002 2 $1200.00
1003 3 $959.00
1004 4 $1416.00

1021 4 $1614.00
1022 3 $232.00

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 115 -

1023 6 $824.00
该结果将 items 表的行收集到具有相同订单号的组中,并计算每个组中行的 COUNT 和价
格的 SUM。
不能在 GROUP BY 子句中包含 TEXT 、BYTE 、CLOB 或 BLOB 列。要进行分组,必
须能够进行排序,并且这些数据类型不存在自然排序顺序。
与 ORDER BY 子句不同,GROUP BY 子句不对数据进行排序。如果想要按特定顺序对数
据进行排序,或在投影列表中的聚集上排序,那么在 GROUP BY 子句之后包含 ORDER
BY 子句。
下列查询与图 4相同,但包括 ORDER BY 子句以按 price 的升序对检索到的行进行排序,
如下所示。
图: 查询
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY order_num
ORDER BY price;
图: 查询结果
order_num number price

1010 2 $84.00
1011 1 $99.00
1013 4 $143.80
1022 3 $232.00
1001 1 $250.00
1020 2 $438.00
1006 5 $448.00

1002 2 $1200.00
1004 4 $1416.00
1014 2 $1440.00
1019 1 $1499.97
1021 4 $1614.00
1007 5 $1696.00
选择特定列一节描述如何在 ORDER BY 子句中使用整数来指示投影列表中列的位置。还
可以在 GROUP BY 子句中使用整数来指示列名的位置或在 GROUP BY 列表中显示标
号。
以下查询返回与图 6所示相同的行。

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 116 -

图: 查询
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY 1
ORDER BY 3;
构建查询时,
Projection 子句的投影列表中的所有非聚集列还必须包含在 GROUP BY 子句
中。
具有 GROUP BY 子句的 SELECT 语句必须针对每一组返回一行。
列出在 GROUP BY
后面的列能够在一组中只反映一个特异值。
并且可以返回该值。
但是,
未列出在 GROUP BY
后面的列可在包含在组中的行中包含不同的值。
下列查询显示如何在连接表的 SELECT 语句中使用 GROUP BY 子句。
图: 查询
SELECT o.order_num, SUM (i.total_price)
FROM orders o, items i
WHERE o.order_date > '01/01/98'
AND o.customer_num = 110
AND o.order_num = i.order_num
GROUP BY o.order_num;
该查询连接 orders 和 items 表,将表别名指定给它们,并返回以下所示的行。
图: 查询结果
order_num (sum)

1008 $940.00
1015 $450.00

为了保证备份文件的安全性,选取专门的文件服务器保存备份记录。
用户在文件服务器上设定共享路径,然后在集群主分片节点上,通过mount 命令,
以nfs 方式进行共享路径的挂载,可以将备份记录保存在远程的文件服务器上。
这样做优点如下:

备份记录文件可以存储在远程的文件服务器上;

备份记录文件的安全性可以得到保证;
假如整个集群内共计包含2 个主分片节点,我们选取2 台文件服务器,分别用于保
存每个主分片上的备份记录。
主分片节点及挂载路径如下:
表4- 55 主分片节点及挂载路径
主分片IP
主分片上的路径(将来做为挂载点)

功能说明
存储过程和函数是由CREATE PROCEDURE 和CREATE FUNCTION 语句所创
建的程序。

存储过程通过CALL 语句来调用,而且只能通过输出变量得到返回值。函数
可以像其它函数一样从语句内部来调用(通过调用函数名),并返回一个标
量值。存储程序(过程和函数)也可以调用其它存储程序(过程和函数);

每个存储过程或函数都与一个特定的数据库相联系。当存储程序(过程和函
数)被调用时,隐含的USE database_name 被执行(当存储程序(过程和函

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1335
数)结束时完成),不允许在存储程序(过程和函数)中使用USE 语句。用
户能使用数据库名来限定存储程序(过程和函数)名。这可以用来指明不在
当前数据库中的存储程序(过程和函数)。例如,要调用一个与gbase 数据
库相关联的存储过程p 或函数f,用户可以使用CALL gbase.p()或gbase.f()。
当一个数据库被删除了,所有与它相关的存储程序(过程和函数)也都被删
除了;

GBase 8a MPP Cluster 可以在存储过程中使用标准的SELECT 语句。这样,
一个查询的结果简单直接地传送到客户端。
多个SELECT 语句产生多个结果
集,
所以客户端必须使用一个支持多结果集的GBase 8a MPP Cluster 客户端
库;

要创建一个存储程序(过程和函数),必须具有CREATE ROUTINE 权限。
如果用户创建了PROCEDURE | FUNCTION,那么会自动赋予用户对该PR
OCEDURE | FUNCTION 的ALTER ROUTINE 和EXECUTE 权限者。如果
开启更新日志,用户可能需要SUPER 权限;

在默认情况下,存储程序(过程和函数)与当前的数据库相关联。要显式的
将过程与数据库联系起来,那用户创建存储程序(过程和函数)时需要将它
的名字的格式写为vc_name.database_name.sp_name;

在括号中必须要有参数列表。如果没有参数,应该使用空的参数列表();默
认参数为IN 参数。如果要将一个参数指定为其它类型,则请在参数名前指
定参数类型;

使用RETURNS 子句(只有FUNCTION 才能指定RETURNS 子句)指明函
数的返回类型时,函数体中必须包含一个RETURN 语句;

如果一个存储过程或函数对同样的输入参数得到同样的结果,
则被认为它是"
确定的"(DETERMINISTIC),否则就是"非确定"的(NOT DETERMINIST
IC)。默认是NOT DETERMINISTIC;

就复制来说,使用NOW()函数(或它的同义字)或RAND()并不会生成一个
非确定性程序。对于NOW(),更新日志包括时间戳并能进行正确的复制。如
果在一个程序中只调用一次,RAND()也能正确地复制;

当前DETERMINISTIC 特性是可接受的,但并不被优化器所使用。然而,如
果更新日志被激活,
这个特性将影响到GBase 8a MPP Cluster 是否接受过程
的定义;

以下几个特征参数提供了程序的数据使用信息:

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1336
1. SQL SECURITY 参数用来指明,此程序的执行权限是赋予创建者还是调
用者。
默认的值是DEFINER。
创建者和调用者必须要有对与程序相关的数据
库的访问权。要执行存储程序(过程和函数)必须具有EXECUTE 权限,必
须具有这个权限的用户要么是定义者,要么是调用者,这依赖于如何设置S
QL SECURITY 特征;
2. COMMENT 语句是GBase 8a MPP Cluster 的扩展,可以用来描述存储过
程。可以使用SHOW CREATE PROCEDURE、SHOW CREATE FUNCTI
ON 语句来显示这些信息。

GBase 8a MPP Cluster 允许存储程序(过程和函数)包含DDL 语句(比如
CREATE 和DROP)和SQL 事务语句(比如COMMIT)。这不是标准所需
要的,只是特定的实现;

返回结果集的语句不能用在函数中。这些语句包括不使用INTO 将列值赋给
变量的SELECT 语句,
SHOW 语句等。
对于在函数定义时就返回结果集的语
句返回一个“Not allowed to return a result set from a function”错误(ER_S
P_NO_RETSET_IN_FUNC)。对于在函数运行时才返回结果集的语句,返回
“PROCEDURE%s can't return a result set in the given context”错误(ER_S
P_BADSELECT)。
语法格式
存储过程
CREATE PROCEDURE ([[,…]
[,proc_parameter_n]])
[characteristic ...] routine_body
CREATE FUNCTION ([[,…]
[,func_parameter_n]])
RETURNS
type
[characteristic ...] routine_body
Proc_parameter:
{IN | OUT | INOUT } param_name type
Func_parameter:
Param_name type

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1337
Characteristic:
LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
表5- 167 参数说明
字段名称
含义说明
proc_name
要创建的存储过程的名称,在同一VC 下,存储过程的名称
必须唯一。
存储过程名称只允许a~z、
A~Z、
0~9、下划线,
且不能只包含数字。
proc_parameter
定义存储过程的参数,每一个参数的定义格式是:<参数方
向><参数名称><参数数据类型>。
func_name
要创建的函数的名称,在同一VC 下,函数的名称必须唯一。
函数名称只允许a~z、A~Z、0~9、下划线,且不能只包含
数字。
func_parameter
定义函数的参数,每一个参数的定义格式是:<参数名称><
参数数据类型>。
IN | OUT | INOUT
确定参数是输入、输出还是输入输出,只能取IN、OUT、
INOUT 中的一个。
param_name
参数名称,
在同一个存储过程/函数中必须唯一,
只允许a~z、
A~Z、0~9、下划线,且不能只包含数字;
type
参数数据类型,
取值为GBase 8a MPP Cluster 支持的数据类型
LANGUAGE SQL
说明routine_body 部分是由SQL 语句组成的,SQL 是
LANGUAGE 特性的唯一值,表示当前仅支持SQL 语句。
[NOT]
DETERMINISTIC
指明存储过程执行的结果是否是确定的。
DETERMINISTIC 表示结果是确定的。
每次执行存储过程时,
相同的输入会得到相同的输出。
NOT DETERMINISTIC 表示结果是不确定的,相同的输入可
能得到不同的输出。如果没有指定任意一个值,默认为NOT
DETERMINISTIC
CONTAINS
SQL
|
NO SQL | READS
SQL
DATA
|
MODIFIES
SQL
DATA
表示子程序使用SQL 语句的限制。
CONTAINS SQL 表明子程序包含SQL 语句,
但是不包含读写
数据的语句,默认情况下,系统会指定为CONTAINS SQL;
NO SQL 表明子程序不包含SQL 语句;
READS SQL DATA:说明子程序包含读数据的语句;
MODIFIES SQL DATA 表明子程序包含写数据的语句。
SQL
SECURITY
{
DEFINER
|
INVOKER }
指明谁有权限来执行。
DEFINER 表示只有定义者才能执行,
默认情况下,
系统指定
为DEFINER ;

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1338
字段名称
含义说明
INVOKER 表示拥有权限的调用者可以执行。
COMMENT ‘string’
注释信息,可以用来描述存储过程或函数
routine_body
是一系列的SQL 语句的组合,其中包含一些数据操作以完成
一定的功能逻辑。
可以用BEGIN...END 来表示SQL 代码的开
始和结束
说明

定义存储过程时,
存储过程/函数时名称后面的括号是必需的,
即使没有任
何参数,也不能省略;

如果存储过程、
函数中的routine_body 仅包含一条SQL 语句,则可以省略
BEGIN 和END,否则,在定义存储过程/函数时,必须使用BEGIN...END
结构把相关的SQL 语句组织在一起形成routine_body;

存储过程、函数可以嵌套。
示例
下面是一个使用IN,OUT 参数的简单的存储过程的示例。这个示例在存储过程
定义前,使用delimiter 命令来把语句定界符从“;”变为“//”。这样就允许用在存储
程序体中的“;”定界符传递到服务器,而不是被解释。
注意

“DELIMITER //”语句的作用是将SQL 的结束符设置为“//”,因为默认
的语句结束符为分号“;”,为了避免与存储过程中SQL 语句结束符相冲
突,需要使用DELIMITER 改变存储过程的结束符,并以“END //”结束
存储过程。

存储过程定义完毕之后再使用“DELIMITER ;”恢复默认结束符。
DELIMITER 也可以指定其他符号为结束符。

书写时需注意:结束符前均有空格。如“DELIMITER //”和“END //”语
句的结束符//前均有空格,sql 语句的结束符前也需要有空格。
示例1:创建proce_count 存储过程,并调用。
gbase> DELIMITER //
gbase> CREATE PROCEDURE proc_count (OUT param1 INT,IN param2
VARCHAR(10))
BEGIN
SELECT COUNT(*) INTO param1 FROM ssbm.customer WHERE
c_nation= param2;
END //

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1339
Query OK, 0 rows affected
gbase> CALL proc_count(@count1,'JORDAN') //
Query OK, 0 rows affected
gbase> DELIMITER ;
gbase> SELECT @count1;
+---------+
| @count1 |
+---------+
|
1182 |
+---------+
1 row in set
说明
当使用定界符命令时,
用户应该避免使用反斜杆
(在GBase 8a MPP Cluster 中表
示转义字符)。
示例2:创建含有参数的hello 函数,使用SQL 函数执行操作并返回结果。
gbase> DELIMITER //
gbase> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
RETURN CONCAT('Hello, ',s,'!'); //
Query OK, 0 rows affected
gbase> DELIMITER ;
gbase> SET @result = hello('world');
Query OK, 0 rows affected
gbase> SELECT @result;
+----------------------------------------------------+
| @result
|
+----------------------------------------------------+
| Hello, world
!
|
+----------------------------------------------------+
1 row in set
说明
如果一个函数的RETURN 语句返回的值与函数中RETURNS 子句指明的值类型
不同,返回的值强制转换为函数定义的返回值类型。

GBase 8a MPP Cluster 产品手册
5 数据库管理指南
文档版本953(2022-09-15)
南大通用数据技术股份有限公司
1340
示例3:创建fn_count 函数,过程定义中包含SQL 语句。
gbase> DELIMITER //
gbase> CREATE FUNCTION fn_count (param
varchar(10)) RETURNS
INT
BEGIN
SELECT
COUNT(*)/5
INTO
@count
FROM
ssbm.customer
WHERE c_nation= param;
RETURN @count;
END //
Query OK, 0 rows affected
gbase> DELIMITER ;
gbase> SET @result = fn_count('JORDAN');
Query OK, 0 rows affected
gbase> SELECT @result;
+---------+
| @result |
+---------+
|
236 |
+---------+
1 row in set