华为云用户手册

  • stddev_samp(expression) 描述:样本标准差。 返回类型:对于浮点类型的输入返回double precision,其他输入返回numeric。 示例: 1 2 3 4 5 SELECT STDDEV_SAMP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; stddev_samp ------------------ 289.224359757315 (1 row)
  • stddev(expression) 描述:stddev_samp的别名。 返回类型:对于浮点类型的输入返回double precision,其他输入返回numeric。 示例: 1 2 3 4 5 SELECT STDDEV(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; stddev ------------------ 289.224359757315 (1 row)
  • var_pop(expression) 描述:总体方差(总体标准差的平方)。 返回类型:对于浮点类型的输入返回double precision类型,其他输入返回numeric类型。 示例: 1 2 3 4 5 SELECT VAR_POP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; var_pop -------------------- 83650.692793695475 (1 row)
  • group_concat(expression [ORDER BY {col_name | expr} [ASC | DESC]] [SEPARATOR str_val]) 描述:将列数据使用指定的str_val分隔符,按照ORDER BY子句指定的排序方式拼接成字符串,ORDER BY子句必须指定排序方式,不支持ORDER BY 1的写法。 expression:必选,指定列名或基于列的有效表达式,不支持DISTINCT关键字和VARIADIC参数。 str_val:可选,指定的分隔符,可以是字符串常数或基于分组列的确定性表达式。缺省时表示分隔符为逗号。 返回类型:text group_concat函数仅8.1.2及以上版本支持。 示例: 默认分隔符为逗号: 1 2 3 4 5 SELECT group_concat(sname) FROM group_concat_test; group_concat ------------------------------------------ ADAMS,FORD,JONES,KING,MILLER,SCOTT,SMITH (1 row) group_concat函数支持自定义分隔符: 1 2 3 4 5 SELECT group_concat(sname separator ';') from group_concat_test; group_concat ------------------------------------------ ADAMS;FORD;JONES;KING;MILLER;SCOTT;SMITH (1 row) group_concat函数支持ORDER BY子句,将列数据进行有序拼接: 1 2 3 4 5 SELECT group_concat(sname order by snumber separator ';') FROM group_concat_test; group_concat ------------------------------------------ MILLER;FORD;SCOTT;SMITH;KING;JONES;ADAMS (1 row)
  • stddev_pop(expression) 描述:总体标准差。 返回类型:对于浮点类型的输入返回double precision,其他输入返回numeric。 示例: 1 2 3 4 5 SELECT STDDEV_POP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; stddev_pop ------------------ 289.224294957556 (1 row)
  • var_samp(expression) 描述:样本方差(样本标准差的平方)。 返回类型:对于浮点类型的输入返回double precision类型,其他输入返回numeric类型。 示例: 1 2 3 4 5 SELECT VAR_SAMP(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; var_samp -------------------- 83650.730277028768 (1 row)
  • bit_and(expression) 描述:所有非NULL输入值的按位与(AND),如果全部输入值皆为NULL,那么结果也为NULL 。 返回类型:和参数数据类型相同。 示例: 1 2 3 4 5 SELECT BIT_AND(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; bit_and --------- 0 (1 row)
  • bit_or(expression) 描述:所有非NULL输入值的按位或(OR),如果全部输入值皆为NULL,那么结果也为NULL。 返回类型:和参数数据类型相同 示例: 1 2 3 4 5 SELECT BIT_OR(inv_quantity_on_hand) FROM tpcds.inventory WHERE inv_warehouse_sk = 1; bit_or -------- 1023 (1 row)
  • listagg(expression [, delimiter]) WITHIN GROUP(ORDER BY order-list) 描述:将聚集列数据按WITHIN GROUP指定的排序方式排列,并用delimiter指定的分隔符拼接成一个字符串。 expression:必选。指定聚集列名或基于列的有效表达式,不支持DISTINCT关键字和VARIADIC参数。 delimiter:可选。指定分隔符,可以是字符串常数或基于分组列的确定性表达式,缺省时表示分隔符为空。 order-list:必选。指定分组内的排序方式。 返回类型:text listagg是兼容Oracle 11g2的列转行聚集函数,可以指定OVER子句用作窗口函数。为了避免与函数本身WITHIN GROUP子句的ORDER BY造成二义性,listagg用作窗口函数时,OVER子句不支持ORDER BY的窗口排序或窗口框架。 示例: 聚集列是文本字符集类型: 1 2 3 4 5 6 7 SELECT deptno, listagg(ename, ',') WITHIN GROUP(ORDER BY ename) AS employees FROM emp GROUP BY deptno; deptno | employees --------+-------------------------------------- 10 | CLARK,KING,MILLER 20 | ADAMS,FORD,JONES,SCOTT,SMITH 30 | ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD (3 rows) 聚集列是整型: 1 2 3 4 5 6 7 SELECT deptno, listagg(mgrno, ',') WITHIN GROUP(ORDER BY mgrno NULLS FIRST) AS mgrnos FROM emp GROUP BY deptno; deptno | mgrnos --------+------------------------------- 10 | 7782,7839 20 | 7566,7566,7788,7839,7902 30 | 7698,7698,7698,7698,7698,7839 (3 rows) 聚集列是浮点类型: 1 2 3 4 5 6 7 8 9 SELECT job, listagg(bonus, '($); ') WITHIN GROUP(ORDER BY bonus DESC) || '($)' AS bonus FROM emp GROUP BY job; job | bonus ------------+------------------------------------------------- CLERK | 10234.21($); 2000.80($); 1100.00($); 1000.22($) PRESIDENT | 23011.88($) ANALYST | 2002.12($); 1001.01($) MANAGER | 10000.01($); 2399.50($); 999.10($) SALESMAN | 1000.01($); 899.00($); 99.99($); 9.00($) (5 rows) 聚集列是时间类型: 1 2 3 4 5 6 7 SELECT deptno, listagg(hiredate, ', ') WITHIN GROUP(ORDER BY hiredate DESC) AS hiredates FROM emp GROUP BY deptno; deptno | hiredates --------+------------------------------------------------------------------------------------------------------------------------------ 10 | 1982-01-23 00:00:00, 1981-11-17 00:00:00, 1981-06-09 00:00:00 20 | 2001-04-02 00:00:00, 1999-12-17 00:00:00, 1987-05-23 00:00:00, 1987-04-19 00:00:00, 1981-12-03 00:00:00 30 | 2015-02-20 00:00:00, 2010-02-22 00:00:00, 1997-09-28 00:00:00, 1981-12-03 00:00:00, 1981-09-08 00:00:00, 1981-05-01 00:00:00 (3 rows) 聚集列是时间间隔类型: 1 2 3 4 5 6 7 SELECT deptno, listagg(vacationTime, '; ') WITHIN GROUP(ORDER BY vacationTime DESC) AS vacationTime FROM emp GROUP BY deptno; deptno | vacationtime --------+------------------------------------------------------------------------------------ 10 | 1 year 30 days; 40 days; 10 days 20 | 70 days; 36 days; 9 days; 5 days 30 | 1 year 1 mon; 2 mons 10 days; 30 days; 12 days 12:00:00; 4 days 06:00:00; 24:00:00 (3 rows) 分隔符缺省时,默认为空: 1 2 3 4 5 6 7 SELECT deptno, listagg(job) WITHIN GROUP(ORDER BY job) AS jobs FROM emp GROUP BY deptno; deptno | jobs --------+---------------------------------------------- 10 | CLERKMANAGERPRESIDENT 20 | ANALYSTANALYSTCLERKCLERKMANAGER 30 | CLERKMANAGERSALESMANSALESMANSALESMANSALESMAN (3 rows) listagg作为窗口函数时,OVER子句不支持ORDER BY的窗口排序,listagg列为对应分组的有序聚集: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 SELECT deptno, mgrno, bonus, listagg(ename,'; ') WITHIN GROUP(ORDER BY hiredate) OVER(PARTITION BY deptno) AS employees FROM emp; deptno | mgrno | bonus | employees --------+-------+----------+------------------------------------------- 10 | 7839 | 10000.01 | CLARK; KING; MILLER 10 | | 23011.88 | CLARK; KING; MILLER 10 | 7782 | 10234.21 | CLARK; KING; MILLER 20 | 7566 | 2002.12 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7566 | 1001.01 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7788 | 1100.00 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7902 | 2000.80 | FORD; SCOTT; ADAMS; SMITH; JONES 20 | 7839 | 999.10 | FORD; SCOTT; ADAMS; SMITH; JONES 30 | 7839 | 2399.50 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 9.00 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 1000.22 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 99.99 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 1000.01 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN 30 | 7698 | 899.00 | BLAKE; TURNER; JAMES; MARTIN; WARD; ALLEN (14 rows)
  • percentile_disc(const) within group(order by expression) 描述:返回第一个在排序中位置等于或者超过指定分数的输入值。 输入:const为在0-1之间的数值,expression当前只支持数值类型和interval类型。其中空值不参与计算。 返回类型:对于任何整型数据输入,结果都是NUMERIC类型。否则,与输入数据类型相同。 示例: 1 2 3 4 5 6 7 8 9 10 SELECT percentile_disc(0.3) within group(order by x) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_disc ----------------- 2 (1 row) SELECT percentile_disc(0.3) within group(order by x desc) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_disc ----------------- 4 (1 row)
  • array_agg(expression) 描述:将所有输入值(包括空)连接成一个数组。函数入参不支持数组形式。 返回类型:参数类型的数组。 示例: 创建表employeeinfo,并插入数据: 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE employeeinfo (empno smallint, ename varchar(20), job varchar(20), hiredate date,deptno smallint); INSERT INTO employeeinfo VALUES (7155, 'JACK', 'SALESMAN', '2018-12-01', 30); INSERT INTO employeeinfo VALUES (7003, 'TOM', 'FINANCE', '2016-06-15', 20); INSERT INTO employeeinfo VALUES (7357, 'MAX', 'SALESMAN', '2020-10-01', 30); SELECT * FROM employeeinfo; empno | ename | job | hiredate | deptno -------+-------+----------+---------------------+-------- 7155 | JACK | SALESMAN | 2018-12-01 00:00:00 | 30 7357 | MAX | SALESMAN | 2020-10-01 00:00:00 | 30 7003 | TOM | FINANCE | 2016-06-15 00:00:00 | 20 (3 rows) 查询部门编号为30的所有员工姓名: 1 2 3 4 5 SELECT array_agg(ename) FROM employeeinfo where deptno = 30; array_agg ------------ {JACK,MAX} (1 row) 查询属于同一个部门的所有员工: 1 2 3 4 5 6 7 8 9 10 11 12 13 SELECT deptno, array_agg(ename) FROM employeeinfo group by deptno; deptno | array_agg --------+------------ 30 | {JACK,MAX} 20 | {TOM} (2 rows) SELECT distinct array_agg(ename) OVER (PARTITION BY deptno) FROM employeeinfo; array_agg ------------ {TOM} {JACK,MAX} (2 rows) 查询所有的部门编号且去重: 1 2 3 4 5 6 SELECT array_agg(distinct deptno) FROM employeeinfo group by deptno; array_agg ----------- {20} {30} (2 rows) 查询所有的部门编号去重后按降序排列: 1 2 3 4 5 SELECT array_agg(distinct deptno order by deptno desc) FROM employeeinfo; array_agg ----------- {30,20} (1 row)
  • percentile_cont(const) within group(order by expression) 描述:返回一个对应于目标列排序中指定分位数的值,如有必要就在相邻的输入项之间插入值。其中空值不参与计算。 输入:const为在0-1之间的数值,expression当前只支持数值类型和interval类型。 返回类型: 对于任何整型数据输入,结果都是NUMERIC类型。否则与输入数据类型相同。 Teradata兼容模式下,如果输入为整型,则返回的数据精度只有整数位。 示例: 1 2 3 4 5 6 7 8 9 10 SELECT percentile_cont(0.3) within group(order by x) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_cont ----------------- 2.2 (1 row) SELECT percentile_cont(0.3) within group(order by x desc) FROM (SELECT generate_series(1,5) AS x) AS t; percentile_cont ----------------- 3.8 (1 row)
  • sum(expression) 描述:所有输入行的expression总和。 返回类型: 通常情况下输入数据类型和输出数据类型是相同的,但以下情况会发生类型转换: 对于SMALLINT或INT输入,输出类型为BIGINT。 对于BIGINT输入,输出类型为NUMBER 。 对于浮点数输入,输出类型为DOUBLE PRECISION。 示例: 1 2 3 4 5 SELECT SUM(ss_ext_tax) FROM tpcds.STORE_SALES; sum -------------- 213267594.69 (1 row)
  • median(expression) 描述:所有输入值的中位数值。当前只支持数值类型和interval类型。其中空值不参与计算。 返回类型: 对于任何整型数据输入,结果都是NUMERIC类型。否则与输入数据类型相同。 Teradata兼容模式下,如果输入为整型,则返回的数据精度只有整数位。 示例: 1 2 3 4 5 SELECT MEDIAN(inv_quantity_on_hand) FROM tpcds.inventory; median -------- 500 (1 row)
  • avg(expression) 描述:所有输入值的均值(算术平均)。 返回类型: 对于任何整数类型输入,结果都是NUMBER类型。 对于任何浮点输入,结果都是DOUBLE PRECISION类型。 其他,和输入数据类型相同。 示例: 1 2 3 4 5 SELECT AVG(inv_quantity_on_hand) FROM tpcds.inventory; avg ---------------------- 500.0387129084044604 (1 row)
  • 条件表达式 在执行SQL语句时,可通过条件表达式筛选出符合条件的数据。 条件表达式主要有以下几种: CASE CASE表达式是条件表达式,类似于其他编程语言中的CASE语句。 CASE表达式的语法图请参考图1。 图1 case::= CASE子句可以用于合法的表达式中。condition是一个返回BOOLEAN数据类型的表达式: 如果结果为真,CASE表达式的结果就是符合该条件所对应的result。 如果结果为假,则以相同方式处理随后的WHEN或ELSE子句。 如果各WHEN condition都不为真,表达式的结果就是在ELSE子句执行的result。如果省略了ELSE子句且没有匹配的条件,结果为NULL。 case when嵌套使用时不建议超过3层,解析器在解析时需要将所有涉及字段递归展开,递归过深可能导致内存占用过大。 如果case when很复杂可以直接使用子查询的方式替换,参考子查询表达式。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 CREATE TABLE tpcds.case_when_t1(CW_COL1 INT) DISTRIBUTE BY HASH (CW_COL1); INSERT INTO tpcds.case_when_t1 VALUES (1), (2), (3); SELECT * FROM tpcds.case_when_t1; cw_col1 --------- 3 1 2 (3 rows) SELECT CW_COL1, CASE WHEN CW_COL1=1 THEN 'one' WHEN CW_COL1=2 THEN 'two' ELSE 'other' END FROM tpcds.case_when_t1; cw_col1 | case ---------+------- 3 | other 1 | one 2 | two (3 rows) DROP TABLE tpcds.case_when_t1; DECODE DECODE的语法图请参见图2。 图2 decode::= 将表达式base_expr与后面的每个compare(n) 进行比较,如果匹配返回相应的value(n)。如果没有发生匹配,则返回default。 示例请参见条件表达式函数。 1 2 3 4 5 SELECT DECODE('A','A',1,'B',2,0); case ------ 1 (1 row) COALESCE COALESCE的语法图请参见图3。 图3 coalesce::= COALESCE返回它的第一个非NULL的参数值。如果参数都为NULL,则返回NULL。它常用于在显示数据时用缺省值替换NULL。和CASE表达式一样,COALESCE只计算用来判断结果的参数,即在第一个非空参数右边的参数不会被计算。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 CREATE TABLE tpcds.c_tabl(description varchar(10), short_description varchar(10), last_value varchar(10)) DISTRIBUTE BY HASH (last_value); INSERT INTO tpcds.c_tabl VALUES('abc', 'efg', '123'); INSERT INTO tpcds.c_tabl VALUES(NULL, 'efg', '123'); INSERT INTO tpcds.c_tabl VALUES(NULL, NULL, '123'); SELECT description, short_description, last_value, COALESCE(description, short_description, last_value) FROM tpcds.c_tabl ORDER BY 1, 2, 3, 4; description | short_description | last_value | coalesce -------------+-------------------+------------+---------- abc | efg | 123 | abc | efg | 123 | efg | | 123 | 123 (3 rows) DROP TABLE tpcds.c_tabl; 如果description不为NULL,则返回description的值,否则计算下一个参数short_description;如果short_description不为NULL,则返回short_description的值,否则计算下一个参数last_value;如果last_value不为NULL,则返回last_value的值,否则返回(none)。 1 2 3 4 5 SELECT COALESCE(NULL,'Hello World'); coalesce --------------- Hello World (1 row) NULLIF NULLIF的语法图请参见图4。 图4 nullif::= 只有当value1和value2相等时,NULLIF才返回NULL。否则它返回value1。 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE TABLE tpcds.null_if_t1 ( NI_VALUE1 VARCHAR(10), NI_VALUE2 VARCHAR(10) ) DISTRIBUTE BY HASH (NI_VALUE1); INSERT INTO tpcds.null_if_t1 VALUES('abc', 'abc'); INSERT INTO tpcds.null_if_t1 VALUES('abc', 'efg'); SELECT NI_VALUE1, NI_VALUE2, NULLIF(NI_VALUE1, NI_VALUE2) FROM tpcds.null_if_t1 ORDER BY 1, 2, 3; ni_value1 | ni_value2 | nullif -----------+-----------+-------- abc | abc | abc | efg | abc (2 rows) DROP TABLE tpcds.null_if_t1; 如果value1等于value2则返回NULL,否则返回value1。 1 2 3 4 5 SELECT NULLIF('Hello','Hello World'); nullif -------- Hello (1 row) GREATEST(最大值),LEAST(最小值) GREATEST的语法图请参见图5。 图5 greatest::= 从一个任意数字表达式的列表里选取最大的数值。 1 2 3 4 5 SELECT greatest(9000,155555,2.01); greatest ---------- 155555 (1 row) LEAST的语法图请参见图6。 图6 least::= 从一个任意数字表达式的列表里选取最小的数值。 以上的数字表达式必须都可以转换成一个普通的数据类型,该数据类型将是结果类型。 列表中的NULL值将被忽略。只有所有表达式的结果都是NULL的时候,结果才是NULL。 1 2 3 4 5 SELECT least(9000,2); least ------- 2 (1 row) 示例请参见条件表达式函数。 NVL NVL的语法图请参见图7。 图7 nvl::= 如果value1为NULL则返回value2,如果value1非NULL,则返回value1。 示例: 1 2 3 4 5 SELECT nvl(null,1); nvl ----- 1 (1 row) 1 2 3 4 5 SELECT nvl ('Hello World' ,1); nvl --------------- Hello World (1 row) IF IF的语法图请参见图8。 图8 if::= 当bool_expr为true时,返回expr1,否则返回expr2。 示例请参见条件表达式函数。 IFNULL IFNULL的语法图请参见图9。 图9 ifnull::= 当expr1不为NULL时,返回expr1,否则返回expr2。 示例请参见条件表达式函数。 父主题: 表达式
  • 列操作示例 创建示例表warehouse_t。 1 2 3 4 5 6 7 8 9 10 11 DROP TABLE IF EXISTS warehouse_t; CREATE TABLE warehouse_t ( W_WAREHOUSE_SK INTEGER NOT NULL, W_WAREHOUSE_ID CHAR(16) NOT NULL, W_WAREHOUSE_NAME VARCHAR(20) UNIQUE DEFERRABLE, W_WAREHOUSE_SQ_FT INTEGER , W_COUNTY VARCHAR(30) , W_STATE CHAR(2) DEFAULT 'GA', W_ZIP CHAR(10) ); 向表warehouse_t中增加一个新的字段。 1 ALTER TABLE warehouse_t ADD W_GOODS_CATEGORY int; 修改表中列名信息以及列字段信息。 1 ALTER TABLE warehouse_t CHANGE W_GOODS_CATEGORY W_GOODS_CATEGORY2 DECIMAL NOT NULL COMMENT 'W_GOODS_CATEGORY'; 为表warehouse_t增加主键。 1 ALTER TABLE warehouse_t ADD PRIMARY KEY(w_warehouse_name); 重命名列。 1 ALTER TABLE warehouse_t RENAME W_ZIP TO new_W_ZIP; 向表中增加多列。 1 ALTER TABLE warehouse_t ADD (W_COMMENT VARCHAR(117) NOT NULL, W_COUNT int); 修改表字段的数据类型,并将字段约束设置为非空。 1 ALTER TABLE warehouse_t MODIFY W_WAREHOUSE_SQ_FT varchar(20) NOT NULL; 为表的指定列添加not null约束。 1 ALTER TABLE warehouse_t ALTER COLUMN W_COUNTY SET NOT NULL; 从表中删除一个字段。 1 ALTER TABLE warehouse_t DROP COLUMN W_STATE; 为warehouse_t表增加一个带有on update的timestamp列。 1 ALTER TABLE warehouse_t ADD COLUMN C_TIME timestamp on update current_timestamp; 将warehouse_t表中带有on update的timestamp列删除。 1 ALTER TABLE warehouse_t MODIFY COLUMN C_TIME timestamp on update NULL;
  • 参数说明 表1 ALTER TABLE参数说明 参数 描述 取值范围 IF EXISTS 如果表名不存在时返回一个提示而不是错误。 - ONLY 仅对指定的表名执行操作。 如果不使用ONLY关键字, 该表及其所有子表都将会被更改。 需注意:只允许在父表或子表中添加或删除列,或更改列的类型。 父表及其后代表必须始终具有相同的列和类型。 - table_name 需要修改的表名称。 可以在表名称后面显示地增加*选项来指定包括子表,即表示所有后代表都被扫描,这是默认行为 有效的表名。 new_table_name 表的新名称。 字符串,需符合标识符命名规范。 column_name,column_1_name, column_2_name 现有的或新字段的名称。 有效的字段名。 new_column_name 指定列的新名称。 字符串,需符合标识符命名规范。 constraint_name 约束的名称。 有效的约束名。 new_constraint_name 表约束的新名称。 字符串,需符合标识符命名规范。 schema_name 表所在的模式名称。 有效的模式名 new_schema 修改后新的模式名称。 有效的模式名。 index_name 索引名称。 有效的索引名。 new_owner 表的新所有者的名称。 有效的用户名或角色名。 new_tablespace 表所属的新表空间的名称。 有效的表空间名。 data_type 新字段的类型,或者现有字段的新类型。 字符串,需符合标识符命名规范。 storage_parameter 表的存储参数。 参见表2。 compress_mode 表字段的压缩可选项,当前仅对行存表有效。该子句指定该字段优先使用的压缩算法 - collation 字段排序规则名称。可选字段COLLATE指定了新字段的排序规则,如果省略,排序规则为新字段的默认类型。 - USING expression USING子句声明如何从旧的字段值里计算新的字段值;如果省略,缺省从旧类型向新类型的赋值转换。如果从旧数据类型到新类型没有隐含或者赋值的转换,则必须提供一个USING子句。 - NOT NULL | NULL 设置列是否允许空值。 - integer 带符号的整数常值。当使用PERCENT时表示按照表数据的百分比收集统计信息。 0~100 attribute_option 属性选项。 - PLAIN | EXTERNAL | EXTENDED | MAIN 字段存储模式。 PLAIN必须用于定长的数值(比如integer)并且是内联的、不压缩的。 MAIN用于内联、可压缩的数据。 EXTERNAL用于外部保存、不压缩的数据。使用EXTERNAL将令在text和bytea字段上的子字符串操作更快,但付出的代价是增加了存储空间。 EXTENDED用于外部的压缩数据,EXTENDED是大多数支持非PLAIN存储的数据的缺省。 - CHECK ( expression ) 每次将要插入的新行或者将要被更新的行必须使表达式结果为真才能成功,否则会抛出一个异常并且不会修改数据库。 声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。 目前,CHECK表达式不能包含子查询也不能引用除当前行字段之外的变量。 - DEFAULT default_expr 给字段指定缺省值。 缺省表达式的数据类型必须和字段类型匹配。 缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。 default_expr中若使用后缀操作符(如!),需使用括号括起来。 - UNIQUE [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] index_parameters UNIQUE ( column_name [, ... ] ) [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] index_parameters UNIQUE约束表示表里的一个或多个字段的组合必须在全表范围内唯一。 其中[ NULLS [ NOT ] DISTINCT | NULLS IGNORE ]字段用来指定Unique唯一索引中索引列NULL值的处理方式。具体可参考表3。 默认取值:该参数默认取值为空,即NULL值可重复插入。 - PRIMARY KEY index_parameters PRIMARY KEY ( column_name [, ... ] ) index_parameters 主键约束表明表中的一个或者一些字段只能包含唯一(不重复)的非NULL值。 - DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE 设置该约束是否可推迟,列存暂不支持。 DEFERRABLE:可以推迟到事务结尾使用SET CONSTRAINTS命令检查。 NOT DEFERRABLE:在每条命令之后马上检查。 INITIALLY IMMEDIATE:那么每条语句之后就立即检查它。 INITIALLY DEFERRED:只有在事务结尾才检查它。 - WITH ( {storage_parameter = value} [, ... ] ) 为表或索引指定一个可选的存储参数。 - COMPRESS|NOCOMPRESS NOCOMPRESS:如果指定关键字NOCOMPRESS则不会修改表的现有压缩特性。 COMPRESS:如果指定COMPRESS关键字,则对该表进行批量插入元组时触发该特性。 - CASCADE 级联删除依赖于被依赖字段或者约束的对象(比如引用该字段的视图)。 - RESTRICT 如果字段或者约束还有任何依赖的对象,则拒绝删除该字段。这是缺省行为。 - cache_policy 表缓存策略,仅存算分离3.0版本支持。 默认值为ALL。 取值范围: ALL: 对整个表进行热缓存。 NONE:对整个表进行冷缓存。 HPN:N分区表中前N个分区会被热缓存,其余分区进行冷缓存。 HPL:P1, P2, ... 分区表中在缓存策略中被指定名称的分区会被热缓存,其余分区进行冷缓存。 说明: 对于外表和非分区内表只支持ALL和NONE两种缓存策略。 仅range和list分区内表支持HPN和HPL缓存策略。 表2 storage_parameter参数说明 storage_parameter 参数 参数项 描述 取值范围 分区管理新增的两个选项 PERIOD 设置分区管理中自动创建分区的周期。 说明: 在建表时,如果没有设置该参数,可以通过set的方式添加该参数,并开启自动创建分区功能;如果之前已经设置该参数,则通过set的方式修改该参数。 用户可以通过reset该参数的方式关闭自动创建分区功能,但是在自动删除分区功能存在的情况下,不支持关闭自动创建分区功能。 interval类型。 PERIOD的范围要求以及开启该功能的约束请参考表2中的PERIOD参数。 TTL 设置分区管理中自动删除分区的分区过期时间。 说明: 在建表时,如果没有设置该参数,可以通过set的方式添加该参数,并开启自动删除分区功能;如果之前已经设置该参数,则通过set的方式修改该参数。 用户可以通过reset该参数的方式关闭自动删除分区功能。 interval类型。 TTL的范围要求以及开启该功能的约束请参考表2中的TTL参数。 turbo存储格式列存表新增的选项 enable_turbo_store 设置列存表是否为turbo存储格式。该选项仅9.1.0.100及以上集群版本支持。 说明: 3.0普通列存表不支持设置turbo存储格式,仅3.0 hstore_opt表支持turbo存储格式。 2.0版本列存表无限制。 - 唯一索引中索引列NULL值的处理方式的说明如下: [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ]字段用来指定Unique唯一索引中索引列NULL值的处理方式。 在对插入的新数据和表中原始数据进行列的等值比较时,对于NULL值有以下三种处理方式: NULLS DISTINCT:NULL值互不相等,即NULL值可重复插入。 NULLS NOT DISTINCT:NULL值相等。若索引列全为NULL,则NULL值不可重复插入;部分索引列为NULL,只有非NULL值不相等,才可成功插入数据。 NULLS IGNORE:在等值比较时跳过NULL值。若索引列全为NULL,则NULL值可重复插入;部分索引列为NULL,只有非NULL值不相等,才可成功插入数据。 表3 唯一索引中索引列NULL值的处理方式 字段控制 索引列全为NULL 部分索引列为NULL NULLS DISTINCT 可重复插入 可重复插入 NULLS NOT DISTINCT 不可重复插入 非NULL值相等,不可插入;非NULL值不相等,则插入成功 NULLS IGNORE 可重复插入 非NULL值相等,不可插入;非NULL值不相等,则插入成功
  • 其他参数的选项 列约束column_constraint为: 1 2 3 4 5 6 7 8 [ CONSTRAINT constraint_name ] { NOT NULL | NULL | CHECK ( expression ) | DEFAULT default_expr | UNIQUE [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] index_parameters | PRIMARY KEY index_parameters } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 列的压缩可选项compress_mode为: 1 [ DELTA | PREFIX | DICTIONARY | NUMSTR | NOCOMPRESS ] 根据已有唯一索引为表增加主键约束或唯一约束table_constraint_using_index为: 1 2 3 [ CONSTRAINT constraint_name ] { UNIQUE | PRIMARY KEY } USING INDEX index_name [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 增加外键约束REFEREN CES 为: 1 2 [ CONSTRAINT constraint_name ] FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] } 表约束table_constraint为: 1 2 3 4 5 6 [ CONSTRAINT constraint_name ] { CHECK ( expression ) | UNIQUE [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] ( column_name [, ... ] ) index_parameters | PRIMARY KEY ( column_name [, ... ] ) index_parameters } [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ] 索引参数index_parameters为: 1 2 [ WITH ( {storage_parameter = value} [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ]
  • 列相关的操作column_clause子句 其中列相关的操作column_clause可以是以下子句之一: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ADD [ COLUMN ] column_name data_type [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] | MODIFY [ COLUMN ] column_name data_type | MODIFY [ COLUMN ] column_name [ CONSTRAINT constraint_name ] NOT NULL [ ENABLE ] | MODIFY [ COLUMN ] column_name [ CONSTRAINT constraint_name ] NULL | MODIFY [ COLUMN ] column_name DEFAULT default_expr | MODIFY [ COLUMN ] column_name ON UPDATE on_update_expr | MODIFY [ COLUMN ] column_name COMMENT comment_text | DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ] | ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ] [ USING expression ] | ALTER [ COLUMN ] column_name { SET DEFAULT expression | DROP DEFAULT } | ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL | ALTER [ COLUMN ] column_name SET STATIS TICS [PERCENT] integer | ADD STATISTI CS (( column_1_name, column_2_name [, ...] )) | ADD { INDEX | UNIQUE [ INDEX ] } [ index_name ] ( { { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS LAST ] } [, ...] ) [ USING method ] [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] [ COMMENT 'text' ] LOCAL [ ( { PARTITION index_partition_name } [, ...] ) ] [ WITH ( { storage_parameter = value } [, ...] ) ] | ADD { INDEX | UNIQUE [ INDEX ] } [ index_name ] ({ { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] }[, ...] ) [ USING method ] [ NULLS [ NOT ] DISTINCT | NULLS IGNORE ] [ COMMENT 'text' ] [ WITH ( {storage_parameter = value} [, ... ] ) ] [ WHERE predicate ] | DROP { INDEX | KEY } index_name | CHANGE [ COLUMN ] old_column_name new_column_name data_type [ [ CONSTRAINT constraint_name ] NOT NULL [ ENABLE ] | [ CONSTRAINT constraint_name ] NULL | DEFAULT default_expr | COMMENT 'text' ] | DELETE STATISTICS (( column_1_name, column_2_name [, ...] )) | ALTER [ COLUMN ] column_name SET ( {attribute_option = value} [, ... ] ) | ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) | ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
  • 表操作相关的action子句 具体表操作action可以是以下子句之一: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 column_clause | ADD table_constraint [ NOT VALID ] | ADD table_constraint_using_index | VALIDATE CONSTRAINT constraint_name | DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] | CLUSTER ON index_name | SET WITHOUT CLUSTER | SET ( {storage_parameter = value} [, ... ] ) | RESET ( storage_parameter [, ... ] ) | OWNER TO new_owner | SET TABLESPACE new_tablespace | SET {COMPRESS|NOCOMPRESS} | DISTRIBUTE BY { REPLICATION | ROUNDROBIN | { HASH ( column_name [,...] ) } } | TO { GROUP groupname | NODE ( nodename [, ... ] ) } | ADD NODE ( nodename [, ... ] ) | DELETE NODE ( nodename [, ... ] ) | DISABLE TRIGGER [ trigger_name | ALL | USER ] | ENABLE TRIGGER [ trigger_name | ALL | USER ] | ENABLE REPLICA TRIGGER trigger_name | ENABLE ALWAYS TRIGGER trigger_name | DISABLE ROW LEVEL SECURITY | ENABLE ROW LEVEL SECURITY | FORCE ROW LEVEL SECURITY | NO FORCE ROW LEVEL SECURITY | REFRESH STORAGE ADD table_constraint [ NOT VALID ] 给表增加一个新的约束。与NOT VALID选项组合时,这种约束仅在对外键和CHECK类约束有效。 如果约束条件增加了NOT VALID选项后,表中已有记录是否满足初始约束检查会被跳过。 ADD table_constraint_using_index 根据已有唯一索引为表增加主键约束或唯一约束。 VALIDATE CONSTRAINT constraint_name 验证一个外键或是一个使用NOT VALID选项创建的检查类约束,通过扫描全表来保证所有记录都符合约束条件。如果约束已标记为有效时,什么操作也不会发生。 DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ] 删除一个表上的约束。 CLUSTER ON index_name 为将来的CLUSTER操作选择默认索引。实际上并没有重新盘簇化处理该表。 SET WITHOUT CLUSTER 从表中删除最新使用的CLUSTER索引。这样会影响将来那些没有声明索引的集群操作。 SET ( {storage_parameter = value} [, ... ] ) 修改表的一个或多个存储参数。 RESET ( storage_parameter [, ... ] ) 重置表的一个或多个存储参数。与SET一样,根据参数的不同可能需要重写表才能获得想要的效果。 OWNER TO new_owner 将表、序列、视图的属主改变成指定的用户。 SET {COMPRESS|NOCOMPRESS} 修改表的压缩特性。表压缩特性的改变只会影响后续批量插入的数据的存储方式,对已有数据的存储毫无影响。也就是说,表压缩特性的修改会导致该表中同时存在着已压缩和未压缩的数据。 DISTRIBUTE BY { REPLICATION | ROUNDROBIN | { HASH ( column_name [,...] ) } } 修改表的分布方式,在修改表分布信息的同时会将表数据在物理上按新分布方式重新分布,修改完成后建议对被修改表执行ANALYZE,以便收集全新的统计信息。 本操作属于重大变更操作,涉及表分布信息的修改以及数据的物理重分布,修改过程中会阻塞业务,修改完成后原有业务的执行计划会发生变化,请按照正规变更流程进行。 本操作属于资源密集操作,针对大表的分布方式修改,建议在计算和存储资源充裕情况下进行,保证整个集群和原表所在表空间有足够的剩余空间能存储一张与原表同等大小且按照新分布方式进行分布的表。 TO { GROUP groupname | NODE ( nodename [, ... ] ) } 此语法仅在扩展模式(GUC参数enable_cluster_resize为on时)下可用。该模式谨慎打开,主要供内部扩容工具使用,一般用户不应使用该模式。 ADD NODE ( nodename [, ... ] ) 此语法主要供内部扩容工具使用,一般用户不建议使用。 DELETE NODE ( nodename [, ... ] ) 此语法主要供内部缩容工具使用,一般用户不建议使用。 DISABLE TRIGGER [ trigger_name | ALL | USER ] 禁用trigger_name所表示的单个触发器,或禁用所有触发器,或仅禁用用户触发器(此选项不包括内部生成的约束触发器,例如,可延迟唯一性和排除约束的约束触发器)。 应谨慎使用此功能,因为如果不执行触发器,则无法保证原先期望的约束的完整性。 ENABLE TRIGGER [ trigger_name | ALL | USER ] 启用trigger_name所表示的单个触发器,或启用所有触发器,或仅启用用户触发器。 ENABLE REPLICA TRIGGER trigger_name 触发器触发机制受配置变量session_replication_role的影响,当复制角色为“origin”(默认值)或“local”时,将触发简单启用的触发器。 配置为ENABLE REPLICA的触发器仅在会话处于“replica”模式时触发。 ENABLE ALWAYS TRIGGER trigger_name 无论当前复制模式如何,配置为ENABLE ALWAYS的触发器都将触发。 DISABLE/ENABLE ROW LEVEL SECURITY 开启或关闭表的行访问控制开关。 当开启行访问控制开关时,如果未在该数据表定义相关行访问控制策略,数据表的行级访问将不受影响;如果关闭表的行访问控制开关,即使定义了行访问控制策略,数据表的行访问也不受影响。详细信息参见CREATE ROW LEVEL SECURITY POLICY章节。 NO FORCE/FORCE ROW LEVEL SECURITY 强制开启或关闭表的行访问控制开关。 默认情况,表所有者不受行访问控制特性影响,但当强制开启表的行访问控制开关时,表的所有者(不包含系统管理员用户)会受影响。系统管理员可以绕过所有的行访问控制策略,不受影响。 REFRESH STORAGE 根据OBS冷热表storage_policy所定义的规则,将符合条件的本地热分区切换为存储在OBS上的冷分区。 例如创建OBS冷热表时,设置storage_policy为 'LMT:10',则在执行该操作时可将10日前无修改的分区切为冷存储,存至OBS中。
  • ALTER TABLE语法格式 1 2 ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name ) } action [, ... ]; 修改表已存在字段的数据类型,可同时修改空约束,default值和注释信息,只允许相同大类的类型转换(数值之间,字符串之间,时间之间等)。 ALTER TABLE [ IF EXISTS ] table_name MODIFY ( { column_name data_type | [ CONSTRAINT constraint_name ] NOT NULL [ ENABLE ] | [ CONSTRAINT constraint_name ] NULL | DEFAULT default_expr | COMMENT 'text' } [, ...] ); 重命名表。对名称的修改不会影响所存储的数据;支持新表名前带有原表的schema名,不支持同时修改schema名。 1 2 3 4 ALTER TABLE [ IF EXISTS ] table_name RENAME TO new_table_name; ALTER TABLE [ IF EXISTS ] table_name RENAME TO schema.new_table_name; 重命名表中指定的列。 1 2 ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name )} RENAME [ COLUMN ] column_name TO new_column_name; 重命名表的约束。 1 2 ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name )} RENAME CONSTRAINT constraint_name TO new_constraint_name; 设置表的所属模式。 1 2 ALTER TABLE [ IF EXISTS ] table_name SET SCHEMA new_schema; 这种形式把表移动到另外一个模式。相关的索引、约束都跟着移动。目前序列不支持改变schema。 若该表拥有序列,需要将序列删除,重建,或者取消拥有关系, 才能将表schema更改成功。 要修改一个表的模式,用户必须在新模式上拥有CREATE权限。要把该表添加为一个父表的新子表,用户必须同时又是父表的所有者。要修改所有者,用户还必须是新的所有角色的直接或间接成员,并且该成员必须在此表的模式上有CREATE权限。这些限制规定了该用户不能做出了重建和删除表之外的事情。不过,系统管理员可以以任何方式修改任意表的所有权限。 除了RENAME和SET SCHEMA之外所有动作都可以捆绑在一个经过多次修改的列表中并行使用。比如,可以在一个命令里增加几个字段或修改几个字段的类型。对于大表,此种操作带来的效率提升更明显,原因在于只需要对该大表做一次处理。 增加一个CHECK或NOT NULL约束将会扫描该表,以保证现有的行符合约束要求。 用一个非空缺省值增加一个字段或者改变一个字段的现有类型会重写整个表。对于大表来说,这个操作可能会花很长时间,并且它还临时需要两倍的磁盘空间。 添加多个列。 1 2 ALTER TABLE [ IF EXISTS ] table_name ADD ( { column_name data_type [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ]} [, ...] ); 更新多个列。 1 2 ALTER TABLE [ IF EXISTS ] table_name MODIFY ( { column_name data_type | column_name [ CONSTRAINT constraint_name ] NOT NULL [ ENABLE ] | column_name [ CONSTRAINT constraint_name ] NULL } [, ...] ); 删除指定表上的索引。 1 ALTER TABLE table_name DROP INDEX index_name;
  • 注意事项 只有表的所有者或者被授予了表ALTER权限的用户有权限执行ALTER TABLE命令,系统管理员默认拥有此权限。但要修改表的所有者或者修改表的模式,当前用户必须是该表的所有者或者系统管理员,且该用户是新的所有角色的直接或间接成员。 不支持修改存储参数ORIENTATION。 SET SCHEMA操作不支持修改为系统内部模式,当前仅支持用户模式之间的修改。 列存表支持PARTIAL CLUSTER KEY,不支持外键表级约束。列存表自8.1.1集群版本开始建表时支持创建主键和唯一表级约束。 行存REPLICATION分布表不支持将系统列设置为主键。 列存表只支持添加字段ADD COLUMN、修改字段的数据类型ALTER TYPE、设置单个字段的收集目标SET STATISTICS、支持更改表名称、支持删除字段DROP COLUMN。对于添加的字段和修改的字段类型要求是列存支持的数据类型。ALTER TYPE的USING选项只支持常量表达式和涉及本字段的表达式,暂不支持涉及其他字段的表达式。 列存表支持的字段约束包括NULL、NOT NULL和DEFAULT常量值;对字段约束的修改,当前支持对DEFAULT值的修改(SET DEFAULT)、删除(DROP DEFAULT)和NOT NULL约束的删除; 支持通过ALTER方式对已有列存表添加非空约束NOT NULL以及主键约束。该约束仅8.2.0及以上集群版本支持。 修改列存表存储参数COLVERSION或者enable_delta时,不能与其他ALTER操作同时进行。
  • 示例 创建范围分区表customer_address。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 DROP TABLE IF EXISTS customer_address; CREATE TABLE customer_address ( ca_address_sk INTEGER NOT NULL , ca_address_id CHARACTER(16) NOT NULL , ca_street_number CHARACTER(10) , ca_street_name CHARACTER varying(60) , ca_street_type CHARACTER(15) , ca_suite_number CHARACTER(10) ) DISTRIBUTE BY HASH (ca_address_sk) PARTITION BY RANGE(ca_address_sk) ( PARTITION P1 VALUES LESS THAN(100), PARTITION P2 VALUES LESS THAN(200), PARTITION P3 VALUES LESS THAN(300) ); 创建示例list分区表。 DROP TABLE IF EXISTS data_list; CREATE TABLE data_list( id int, time int, sarlay decimal(12,2) )PARTITION BY LIST (time)( PARTITION P1 VALUES (202209), PARTITION P2 VALUES (202210,202208), PARTITION P3 VALUES (202211), PARTITION P4 VALUES (202212), PARTITION P5 VALUES (202301) ); modify_clause子句用于设置分区索引是否可用。 给分区表customer_address创建LOCAL索引student_grade_index,并指定分区的索引名称。 1 2 3 4 5 6 CREATE INDEX customer_address_index ON customer_address(ca_address_id) LOCAL ( PARTITION P1_index, PARTITION P2_index, PARTITION P3_index ); 重建分区表customer_address中分区P1上的所有索引。 1 ALTER TABLE customer_address MODIFY PARTITION P1 REBUILD UNUSABLE LOCAL INDEXES; 设置分区表customer_address的分区P3上的所有索引不可用。 1 ALTER TABLE customer_address MODIFY PARTITION P3 UNUSABLE LOCAL INDEXES; add_clause子句用于为指定的分区表添加一个或多个分区。 为范围分区表customer_address增加分区。 1 ALTER TABLE customer_address ADD PARTITION P5 VALUES LESS THAN (500); 为范围分区表customer_address增加分区: [500, 600), [600, 700)。 1 ALTER TABLE customer_address ADD PARTITION p6 START(500) END(700) EVERY(100); 为范围分区表customer_address增加MAXVALUE分区p7。 1 ALTER TABLE customer_address ADD PARTITION p7 END(MAXVALUE); 为列表分区表增加分区P6。 1 ALTER TABLE data_list ADD PARTITION P6 VALUES (202302,202303); split_clause子句用于将一个分区切割成多个分区。 将范围分区表customer_address的P7分区以800为分割点切分。 1 ALTER TABLE customer_address SPLIT PARTITION P7 AT(800) INTO (PARTITION P6a,PARTITION P6b); 将范围分区表customer_address中400所在的分区分割成多个分区。 1 ALTER TABLE customer_address SPLIT PARTITION FOR(400) INTO(PARTITION p_part START(300) END(500) EVERY(100)); 将列表分区表data_list的分区P2分割成p2a和p2b两个分区。 1 ALTER TABLE data_list SPLIT PARTITION P2 VALUES(202210) INTO (PARTITION p2a,PARTITION p2b); exchange_clause子句用于将普通表的数据迁移到指定分区。 如下示例将演示一个普通表math_grade数据迁移到分区表student_grade中分区(math)的操作。 创建分区表student_grade。 1 2 3 4 5 6 7 8 9 10 11 12 13 CREATE TABLE student_grade ( stu_name char(5), stu_no integer, grade integer, subject varchar(30) ) PARTITION BY LIST(subject) ( PARTITION gym VALUES('gymnastics'), PARTITION phys VALUES('physics'), PARTITION history VALUES('history'), PARTITION math VALUES('math') ); 插入数据到分区表student_grade中。 1 2 3 4 5 6 7 INSERT INTO student_grade VALUES ('Ann', 20220101, 75, 'gymnastics'), ('Jeck', 20220103, 60, 'math'), ('Anna', 20220108, 56, 'history'), ('Jann', 20220107, 82, 'physics'), ('Molly', 20220104, 91, 'physics'), ('Sam', 20220105, 72, 'math'); 查询分区表student_grade的math分区记录。 1 SELECT * FROM student_grade PARTITION (math); 查询结果如下: stu_name | stu_no | grade | subject ----------+----------+-------+--------- Jeck | 20220103 | 60 | math Sam | 20220105 | 72 | math (2 rows) 创建一个与分区表student_grade定义匹配的普通表math_grade。 1 2 3 4 5 6 7 CREATE TABLE math_grade ( stu_name char(5), stu_no integer, grade integer, subject varchar(30) ); 插入数据到表math_grade中。数据与分区表student_grade的math分区的分区规则一致。 1 2 3 4 5 INSERT INTO math_grade VALUES ('Ann', 20220101, 75, 'math'), ('Jeck', 20220103, 60, 'math'), ('Anna', 20220108, 56, 'math'), ('Jann', 20220107, 82, 'math'); 将普通表math_grade数据迁移到分区表student_grade的分区(math)。 1 ALTER TABLE student_grade EXCHANGE PARTITION (math) WITH TABLE math_grade; 查询分区表student_grade,结果显示表math_grade中的数据已和分区表student_grade的分区math中的数据交换。 1 SELECT * FROM student_grade PARTITION (math); 1 2 3 4 5 6 7 stu_name | stu_no | grade | subject ----------+----------+-------+--------- Anna | 20220108 | 56 | math Jeck | 20220103 | 60 | math Ann | 20220101 | 75 | math Jann | 20220107 | 82 | math (4 rows) 查询表math_grade,显示之前存储在分区表student_grade的分区math中的数据已交换到表math_grade中。 1 SELECT * FROM math_grade; 1 2 3 4 5 stu_name | stu_no | grade | subject ----------+----------+-------+--------- Jeck | 20220103 | 60 | math Sam | 20220105 | 72 | math (2 rows) truncate_partitioned_clause子语法用于清理表分区的数据。 清空表customer_address分区p1: 1 ALTER TABLE customer_address TRUNCATE PARTITION p1; row_clause子句用于设置分区表的行迁移开关。 打开分区表customer_address的迁移开关。 1 ALTER TABLE customer_address ENABLE ROW MOVEMENT; merge_clause子句用于把多个分区合并成一个分区。 将范围分区表customer_address的P2,P3两个分区合并为一个分区。 1 ALTER TABLE customer_address MERGE PARTITIONS P2, P3 INTO PARTITION P_M; drop_clause子句用于删除分区表中的指定分区。 删除分区表customer_address的多个分区P6a,P6b。 1 ALTER TABLE customer_address DROP PARTITION P6a, P6b;
  • 参数说明 表1 ALTER TABLE PARTITION参数说明 参数 描述 取值范围 table_name 需要修改的分区表的名称。 已存在的分区表名。 partition_name 需要修改的分区名。 已存在的分区名。 partition_value 分区键值。 通过PARTITION FOR ( partition_value [, ...] )子句指定的这一组值,可以唯一确定一个分区。 需要进行重命名分区的分区键的取值范围。 UNUSABLE LOCAL INDEXES 设置该分区上的所有索引不可用。 - REBUILD UNUSABLE LOCAL INDEXES 重建该分区上的所有索引。 - WITHOUT UNUSABLE 重建该分区上的索引时,忽略UNUSABLE状态的索引。 - ENABLE/DISABLE ROW MOVEMENT 行迁移开关。默认是关闭状态。 说明: ENABLE ROW MOVEMENT开启则允许跨分区更新,但此时如果有SELECT FOR UPDATE查询该分区表并发执行,存在查询结果瞬时不一致的可能性,需要谨慎使用。 如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。 ENABLE:打开行迁移开关。 DISABLE:关闭行迁移开关。 ordinary_table_name 进行迁移的普通表的名称。 已存在的普通表名。 { WITH | WITHOUT } VALIDATION 在进行数据迁移时,是否检查普通表中的数据满足指定分区的分区键范围。默认为WITH。 由于检查比较耗时,特别是当数据量很大的情况下更甚。所以在保证当前普通表中的数据满足分区的分区键范围时,可以加上WITHOUT来指明不进行检查。 WITH:对于普通表中的数据要检查是否满足分区的分区键范围,如果有数据不满足,则报错。 WITHOUT:对于普通表中的数据不检查是否满足分区的分区键范围。 VERBOSE 在VALIDATION是WITH状态时,如果检查出普通表有不满足要交换分区的分区键范围的数据,那么把这些数据插入到正确的分区,如果路由不到任何分区,再报错。 须知: 只有在VALIDATION是WITH状态时,才可以指定VERBOSE。 - partition_new_name 分区的新名称。 字符串,需符合标识符命名规范。
  • 语法格式 修改表分区主语法。 1 2 ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name )} action [, ... ]; 其中action统指如下分区维护子语法。当存在多个分区维护子句时,保证了分区的连续性,无论这些子句的排序如何, GaussDB (DWS)总会先执行DROP PARTITION再执行ADD PARTITION操作,最后顺序执行其它分区维护操作。 1 2 3 4 5 6 7 8 9 10 modify_clause | rebuild_clause | exchange_clause | row_clause | merge_clause | modify_clause | split_clause | add_clause | drop_clause | truncate_partitioned_clause modify_clause子语法用于设置分区索引是否可用。 1 MODIFY PARTITION partition_name { UNUSABLE LOCAL INDEXES | REBUILD UNUSABLE LOCAL INDEXES } rebuild_clause子语法用来重建分区的索引。该语法仅8.3.0.100及以上集群版本支持。 1 REBUILD PARTITION partition_name [ WITHOUT UNUSABLE ] exchange_clause子语法用于把普通表的数据迁移到指定的分区。 1 2 3 EXCHANGE PARTITION { ( partition_name ) | FOR ( partition_value [, ...] ) } WITH TABLE {[ ONLY ] ordinary_table_name | ordinary_table_name * | ONLY ( ordinary_table_name )} [ { WITH | WITHOUT } VALIDATION ] [ VERBOSE ] 进行交换的普通表和分区表必须满足如下条件: 普通表和分区表的列数目相同,对应列的信息严格一致,包括:列名、列的数据类型、列约束、列的Collation信息、列的存储参数、列的压缩信息、已删除字段的数据类型等。 普通表和分区表的表压缩信息严格一致。 普通表和分区表的分布列信息严格一致。 普通表和分区表的索引个数相同,且对应索引的信息严格一致。 普通表和分区表的表约束个数相同,且对应表约束的信息严格一致。 普通表不可以是临时表和unlogged表。 普通表和分区表应该在同一个逻辑集群或节点组(NodeGroup)中,如果不在同一个逻辑集群或节点组,将会采用将数据插入对方表内方式来实现交换分区,这样交换分区的时间与表数据量有关,对于数据量非常大的表和分区表,交换分区将会非常耗时。 在线扩容重分布场景中,如果普通表和分区表正在重分布,交换分区语句有可能中断正在重分布的普通表或分区表(取决于交换分区和重分布语句是否产生锁冲突),通常重分布的普通表或分区表被中断后会重试2次,但同一个表交换分区执行过于频繁可能导致普通表或分区表多次重试重分布都失败。如果普通表重分布过程被交换分区操作打断,在重试重分布时,数据已经被替换为原分区表中的数据,会重新进行全量重分布。 如果行存分区表中最后一个有效字段后的其他字段全部被删除,在不考虑这些删除字段的情况下,分区表与普通表字段信息一致时,分区表和普通表可以进行交换。 列存普通表和列存分区表的表级参数colversion必须一致:禁止colversion2.0与colversion1.0执行交换分区操作。 完成交换后,普通表和分区表的数据被置换,同时普通表和分区表的表空间信息被置换。此时,普通表和分区表的统计信息变得不可靠,需要对普通表和分区表重新执行analyze。 row_clause子语法用于设置分区表的行迁移开关。 1 { ENABLE | DISABLE } ROW MOVEMENT merge_clause子语法用于把多个分区合并成一个分区。 1 MERGE PARTITIONS { partition_name } [, ...] INTO PARTITION partition_name INTO关键字前的分区称为源分区,INTO关键字后的分区称为目标分区。 源分区个数不能小于2个。 源分区名称不能重复。 源分区不能存在unusable的索引,否则执行会报错。 目标分区名只能跟最后一个源分区的名称相同,或者跟表的所有分区名都不相同。 目标分区的边界是所有源分区边界的并集。 对于范围分区表,所有的源分区必须是边界连续的分区。 对于列表分区,如果源分区中包含DEFAULT分区,那么目标分区的边界也是DEFAULT。 modify_clause子语法用于设置分区索引是否可用。 1 MODIFY PARTITION partition_name { UNUSABLE LOCAL INDEXES | REBUILD UNUSABLE LOCAL INDEXES } split_clause子语法用于把一个分区切割成多个分区。 范围分区的split_clause语法如下: 1 SPLIT PARTITION { partition_name | FOR ( partition_value [, ...] ) } { split_point_clause | no_split_point_clause } 指定切割点split_point_clause的语法为: 1 AT ( partition_value ) INTO ( PARTITION partition_name , PARTITION partition_name ) 切割点的大小要位于正在被切割分区的分区键范围内,指定切割点的方式只能把一个分区切割成两个新分区。 不指定切割点no_split_point_clause的语法为。 1 INTO { ( partition_less_than_item [, ...] ) | ( partition_start_end_item [, ...] ) } 不指定切割点的方式,partition_less_than_item指定的第一个新分区的分区键要大于正在被切割的分区的前一个分区(如果存在的话)的分区键,partition_less_than_item指定的最后一个分区的分区键要等于正在被切割分区的分区键大小。 不指定切割点的方式,partition_start_end_item指定的第一个新分区的起始点(如果存在的话)必须等于正在被切割的分区的前一个分区(如果存在的话)的分区键,partition_start_end_item指定的最后一个分区的终止点(如果存在的话)必须等于正在被切割分区的分区键。 partition_less_than_item支持的分区键个数最多为4,而partition_start_end_item仅支持1个分区键,其支持的数据类型参见表1中的“PARTITION BY RANGE(partition_key)”参数。 在同一语句中partition_less_than_item和partition_start_end_item两者不可同时使用;不同split语句之间没有限制。 分区项partition_less_than_item的语法为: 1 2 PARTITION partition_name VALUES LESS THAN ( { partition_value | MAXVALUE } [, ...] ) 分区项partition_start_end_item的语法为,其约束参见表1中的“partition_start_end_item”参数。 1 2 3 4 5 6 PARTITION partition_name { {START(partition_value) END (partition_value) EVERY (interval_value)} | {START(partition_value) END ({partition_value | MAXVALUE})} | {START(partition_value)} | {END({partition_value | MAXVALUE})} } 列表分区的split_clause语法如下: 1 SPLIT PARTITION { partition_name | FOR ( partition_value [, ...] ) } { split_values_clause | split_no_values_clause } 指定切割点的split_values_clause的语法为: 1 VALUES ( { (partition_value) [, ...] } | DEFAULT } ) INTO ( PARTITION partition_name , PARTITION partition_name ) 如果源分区不是DEFAULT分区,那么切割点所指定的边界是源分区边界的一个非空真子集;如果源分区是DEFAULT分区,那么切割点所指定的边界不能和其它非DEFAULT分区的边界存在重叠。 切割点的指定的边界是INTO关键字后面的第一个分区的边界,源分区边界与切割点的指定的边界的差集是第二个分区的边界。 当源分区是DEFAULT分区时,第二个分区的边界还是DEFAULT。 不指定切割点的split_no_values_clause的语法为: 1 INTO ( list_partition_item [, ....], PARTITION partition_name ) 此处的list_partition_item和创建列表分区表的时候指定分区的语法一样,除了此处的分区定义中边界值不能为DEFAULT。 除了最后一个分区,其他分区需要显式定义边界,定义的边界不能是DEFAULT,并且必须是源分区边界的非空真子集。最后一个分区的边界是源分区边界与其它分区边界的差集,且最后一个分区的边界为空(即差集不能为空集)。 如果源分区是DEFAULT分区,则最后一个分区的边界为DEFAULT。 add_clause子语法用于为指定的分区表添加一个或多个分区。 范围分区的add_clause语法如下: 1 ADD { partition_less_than_item... | partition_start_end_item } 使用partition_less_than_item语法时,分区表必须是范围分区表,否则执行会报错。 此处partition_less_than_item和创建范围分区表的时候指定分区的语法一样。 当前分区表的最后一个分区的边界为MAXVALUE,不允许添加新的分区,否则执行会报错。 列表分区的add_clause语法如下: 1 ADD list_partition_item 使用list_partition_item语法时,分区表必须是列表分区表,否则执行会报错 此处的list_partition_item和创建列表分区表的时候指定分区的语法一样 当前分区表存在DEFAULT分区时,不允许添加新的分区动作,否则执行会报错 drop_clause子语法用于删除分区表中的指定分区。 1 DROP PARTITION { partition_name | FOR ( partition_value [, ...] ) } drop_clause子语法支持删除多个分区语法。(8.1.3.100及以上集群版本支持。) 1 DROP PARTITION { partition_name [, ... ] } truncate_partitioned_clause子语法用于清理表分区的数据。 1 TRUNCATE PARTITION { partition_name | FOR ( partition_value [, ...] ) }; partition_value为分区键值。支持指定多个分区键值,多个分区键值以英文逗号分隔。 使用PARTITION FOR子句时,partition_value所在的整个分区会被清空。 修改表分区名称的语法。 1 2 ALTER TABLE [ IF EXISTS ] { table_name [*] | ONLY table_name | ONLY ( table_name )} RENAME PARTITION { partition_name | FOR ( partition_value [, ...] ) } TO partition_new_name;
  • 注意事项 添加分区的名称不能与该分区表已有分区的名称相同。 对于范围分区表,要添加的分区的边界值要和分区表的分区键的类型一致,且要大于分区表的最后一个分区的上边界。 对于列表分区表,如果已经定义DEFAULT分区,则不能添加新分区。 若文档中未特殊注明,则表明范围分区表和列存分区的语法使用相同。 如果目标分区表中已有分区数达到了最大值(32767),则不能继续添加分区。 当分区表只有一个分区时,不能删除该分区。 删除分区(DROP PARTITION)时会连同分区内数据一起删除。 选择分区使用PARTITION FOR(),括号里指定值个数应该与定义分区时使用的列个数相同,并且一一对应。 Value分区表不支持相应的Alter Partition操作。 OBS冷热表对于move,exchange,merge,split操作,不支持指定分区表的表空间为OBS表空间;执行ALTER语法时,需保持分区数据冷热属性不变(即冷分区操作后为冷分区,热分区操作后为热分区),不支持将冷分区数据切至本地表空间;对于冷分区仅支持默认表空间;merge操作不支持将冷分区与热分区进行合并,exchange操作不支持冷分区交换。 避免在业务高峰期执行ALTER TABLE/ALTER TABLE PARTITION(增删改查、DROP PARTITION)、TRUNCATE操作,避免有长SQL阻塞ALTER、TRUNCATE操作或SQL业务被ALTER、TRUNCATE阻塞。 更多开发设计规范参见总体开发设计规范。
  • 8.3.0.101 表5 8.3.0.101新增功能/解决问题列表 类别 功能或问题描述 问题原因 问题出现版本 修复建议 新增功能 vacuum full适配binlog表。 - - - 解决问题 analyze语句报错Could not open file "pg_clog/000000000075" 列存表进行vacuumfull后可能提前回收clog,导致主备切换后进行analyze时无法访问clog文件。 8.3.0.100 升级到8.3.0.101及以上版本 使用\parallel on高并发下创建job报错duplicate key value violates unique constraint "pg_jobs_id_index" ,Key(job_id)=() already exists。 获取job_id处的锁未成功加上,导致并发时取到相同job_id报错。 8.3.0.100 多个nodegroup场景下,重分布不支持跳过指定表,导致缩容失败。 重分布不支持跳过指定表。 8.3.0.100 执行Hstore用例,网卡故障时,因为内存为超大负数,导致用例执行失败。 临时变量声明后,未赋值导致参数值非预期,后续再去扣减内存,内存出现超大负数。 8.3.0.100
  • 8.3.0.105 表3 8.3.0.105新增功能/解决问题列表 类别 功能或问题描述 问题原因 问题出现版本 修复建议 新增功能 无 - - - 解决问题 多count distinct走share scan出现结果集错误 sharescan计划生成时,CTE子查询误用了上层的等价类信息,造成分布列判断错误,生成计划缺少数据重分布算子 8.3.0.105以前版本 升级到8.3.0.105及以上版本 升级到830版本后系统表autovacuum未生效 升级830前做过容灾迁移,容灾迁移会先设置autovacuum_max_workers为0,再修改成原来的默认值3,导致升级后未将该值设为预期的值6 8.3.0.105以前版本 修复UDF在recv接收数据时,可能存在超时后error为EAGAIN但没有被捕获直接报错的问题 当cn_retry开启时,socket recv 20s超时后,EAGAIN的错误码没有被捕获,直接走到报错逻辑 8.3.0.105以前版本
  • 8.3.0.110 表1 8.3.0.110新增功能/解决问题列表 类别 功能或问题描述 问题原因 问题出现版本 修复建议 新增功能 新安装集群默认打开全局死锁检测功能,之前版本默认没有打开。 - - - 解决问题 当一个常用表达式(Common Table Expressions,简称CTE)仅被另一个CTE引用多次时可能触发空指针访问导致故障。 当一个CTE仅被另一个CTE引用多次时,计划递归遍历逻辑错误导致访问空指针,产生集群故障。 8.3.0.101 升级到8.3.0.110及以上版本 列存表查询语句中出现多结果集函数时,执行该语句会报错Set-returning function is not supported in vector engine。 非表的scan算子上的向量化执行引擎不支持多结果集函数。 8.3.0.101 集群低版本升级到8.3.0版本时,线程池功能失效。 集群低版本升级到8.3.0时,需要根据当前硬件配置设置max_stream_pool,因为默认单位识别异常,导致max_stream_pool被设置为0。 8.3.0.101 使用parquet外表查询报错The parameter destMax is too small or parameter count is larger than macro parameter。 parquet外表的string类型字段的缓冲区空间管理错位,导致大于1K的字段内存分配不够,引起业务报错。 8.3.0.101 正在数据重分布的冷热表进行分区交换操作时报错Multi-temperature table only support column partition table。 重分布过程中创建的临时表引用了原表的冷热表属性,导致临时表创建失败。 8.3.0.101
共100000条
提示

您即将访问非华为云网站,请注意账号财产安全