云服务器内容精选

  • 操作步骤 参见创建DWS 3.0集群创建DWS 3.0集群,集群创建后默认会转换成逻辑集群v3_logical。 通过节点扩容方式增加3个节点到弹性集群,再添加逻辑集群lc2。 创建用户u1,并关联逻辑集群v3_logical。 1 CREATE USER u1 with SYSADMIN NODE GROUP "v3_logical" password "Password@123"; 创建用户u2,并关联逻辑集群lc2。 1 CREATE USER u2 with SYSADMIN NODE GROUP "lc2" password "Password@123"; 以u1登录数据库,创建表t1和t2,并插入测试数据。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CREATE TABLE public.t1 ( id integer not null, data integer, age integer ) WITH (ORIENTATION =COLUMN, COLVERSION =3.0) DISTRIBUTE BY ROUNDROBIN; CREATE TABLE public.t2 ( id integer not null, data integer, age integer ) WITH (ORIENTATION = COLUMN, COLVERSION =3.0) DISTRIBUTE BY ROUNDROBIN; INSERT INTO public.t1 VALUES (1,2,10),(2,3,11); INSERT INTO public.t2 VALUES (1,2,10),(2,3,11); 以u2登录数据库,执行以下命令查询t1和写入数据。 从结果可得出,实现用户u2跨逻辑集群进行查询和写入数据的能力。 1 2 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t2;
  • WITH中的数据修改语句 在WITH子句中使用数据修改命令INSERT、UPDATE、DELETE。这允许用户在同一个查询中执行多个不同操作。示例如下所示: 1 2 3 4 5 6 WITH moved_tree AS ( DELETE FROM tree WHERE parentid = 4 RETURNING * ) INSERT INTO tree_log SELECT * FROM moved_tree; 上述查询示例实际上从tree把行移动到tree_log。WITH中的DELETE删除来自tree的指定行,以它的RETURNING子句返回它们的内容,并且接着主查询读该输出并将它插入到tree_log。 WITH子句中的数据修改语句必须有RETURNING子句,用来返回RETURNING子句的输出,而不是数据修改语句的目标表,RETURNING子句形成了可以被查询的其余部分引用的临时表。如果一个WITH中的数据修改语句缺少一个RETURNING子句,则它形不成临时表并且不能在剩余的查询中被引用。 如果声明了RECURSIVE关键字,则不允许在数据修改语句中进行递归自引用。在某些情况中可以通过引用递归WITH的输出来绕过这个限制,例如: 1 2 3 4 5 6 7 8 9 WITH RECURSIVE included_parts(sub_part, part) AS ( SELECT sub_part, part FROM parts WHERE part = 'our_product' UNION ALL SELECT p.sub_part, p.part FROM included_parts pr, parts p WHERE p.part = pr.sub_part ) DELETE FROM parts WHERE part IN (SELECT part FROM included_parts); 这个查询将会移除一个产品的所有直接或间接子部件。 WITH子句中的子语句与主查询同时执行。因此,在使用WITH中的数据修改语句时,指定更新的顺序实际是以不可预测的方式发生的。所有的语句都使用同一个快照中执行,语句的效果在目标表上不可见。这减轻了行更新的实际顺序的不可预见性的影响,并且意味着RETURNING数据是在不同WITH子语句和主查询之间传达改变的唯一方法。 本示例中外层SELECT可以返回更新之前的数据: 1 2 3 4 WITH t AS ( UPDATE tree SET id = id + 1 RETURNING * ) SELECT * FROM tree; 本示例中外部SELECT将返回更新过的数据: 1 2 3 4 WITH t AS ( UPDATE tree SET id = id + 1 RETURNING * ) SELECT * FROM t; 不支持在单个语句中更新同一行两次。这种语句的效果是不可预测的。如果只有一个修改发生了,但却不容易(有时也不可能)预测哪一个发生了修改。
  • WITH递归查询 通过声明RECURSIVE关键字,一个WITH查询可以引用它自己的输出。 递归WITH查询的通常形式如下: 1 non_recursive_term UNION [ALL] recursive_term 其中:UNION在合并集合时会执行去重操作,而UNION ALLL则直接将结果集合并、不执行去重;只有递归项能够包含对于查询自身输出的引用。 使用递归WITH时,必须确保查询的递归项最终不会返回元组,否则查询将无限循环。 使用表tree来存储下图中的所有节点信息: 表定义语句如下: 1 CREATE TABLE tree(id INT, parentid INT); 表中数据如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 INSERT INTO tree VALUES(1,0),(2,1),(3,1),(4,2),(5,2),(6,3),(7,3),(8,4),(9,4),(10,6),(11,6),(12,10); SELECT * FROM tree; id | parentid ----+---------- 1 | 0 2 | 1 3 | 1 4 | 2 5 | 2 6 | 3 7 | 3 8 | 4 9 | 4 10 | 6 11 | 6 12 | 10 (12 rows) 通过以下WITH RECURSIVE语句,我们可以返回从顶层1号节点开始,整个树的节点,以及层次信息: 1 2 3 4 5 6 7 8 9 10 11 WITH RECURSIVE nodeset AS ( -- recursive initializing query SELECT id, parentid, 1 AS level FROM tree WHERE id = 1 UNION ALL -- recursive join query SELECT tree.id, tree.parentid, level + 1 FROM tree, nodeset WHERE tree.parentid = nodeset.id ) SELECT * FROM nodeset ORDER BY id; 上述查询中,我们可以看出,一个典型的WITH RECURSIVE表达式包含至少一个递归查询的CTE,该CTE中的定义为一个UNION ALL集合操作,第一个分支为递归起始查询,第二个分支为递归关联查询,需要自引用第一部分进行不断递归关联。该语句执行时,递归起始查询执行一次,关联查询执行若干次并将结果叠加到起始查询结果集中,直到某一些关联查询结果为空,则返回。 上述查询的执行结果如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 id | parentid | level ----+----------+------- 1 | 0 | 1 2 | 1 | 2 3 | 1 | 2 4 | 2 | 3 5 | 2 | 3 6 | 3 | 3 7 | 3 | 3 8 | 4 | 4 9 | 4 | 4 10 | 6 | 4 11 | 6 | 4 12 | 10 | 5 (12 rows) 从返回结果可以看出,起始查询结果包含level=1的结果集,关联查询执行了五次,前四次分别输出level=2,3,4,5的结果集,在第五次执行时,由于没有parentid和输出结果集id相等的记录,也就是再没有多余的孩子节点,因此查询结束。 对于WITH RECURSIVE表达式, GaussDB (DWS)支持其分布式执行。由于WITH RECURSIVE涉及到循环运算,GaussDB(DWS)引入了参数max_recursive_times,用于控制WITH RECURSIVE的最大循环次数,默认值为200,超过该次数则报错。
  • WITH中的数据修改语句 在WITH子句中使用数据修改命令INSERT、UPDATE、DELETE。这允许用户在同一个查询中执行多个不同操作。示例如下所示: 1 2 3 4 5 6 WITH moved_tree AS ( DELETE FROM tree WHERE parentid = 4 RETURNING * ) INSERT INTO tree_log SELECT * FROM moved_tree; 上述查询示例实际上从tree把行移动到tree_log。WITH中的DELETE删除来自tree的指定行,以它的RETURNING子句返回它们的内容,并且接着主查询读该输出并将它插入到tree_log。 WITH子句中的数据修改语句必须有RETURNING子句,用来返回RETURNING子句的输出,而不是数据修改语句的目标表,RETURNING子句形成了可以被查询的其余部分引用的临时表。如果一个WITH中的数据修改语句缺少一个RETURNING子句,则它形不成临时表并且不能在剩余的查询中被引用。 如果声明了RECURSIVE关键字,则不允许在数据修改语句中进行递归自引用。在某些情况中可以通过引用递归WITH的输出来绕过这个限制,例如: 1 2 3 4 5 6 7 8 9 WITH RECURSIVE included_parts(sub_part, part) AS ( SELECT sub_part, part FROM parts WHERE part = 'our_product' UNION ALL SELECT p.sub_part, p.part FROM included_parts pr, parts p WHERE p.part = pr.sub_part ) DELETE FROM parts WHERE part IN (SELECT part FROM included_parts); 这个查询将会移除一个产品的所有直接或间接子部件。 WITH子句中的子语句与主查询同时执行。因此,在使用WITH中的数据修改语句时,指定更新的顺序实际是以不可预测的方式发生的。所有的语句都使用同一个快照中执行,语句的效果在目标表上不可见。这减轻了行更新的实际顺序的不可预见性的影响,并且意味着RETURNING数据是在不同WITH子语句和主查询之间传达改变的唯一方法。 本示例中外层SELECT可以返回更新之前的数据: 1 2 3 4 WITH t AS ( UPDATE tree SET id = id + 1 RETURNING * ) SELECT * FROM tree; 本示例中外部SELECT将返回更新过的数据: 1 2 3 4 WITH t AS ( UPDATE tree SET id = id + 1 RETURNING * ) SELECT * FROM t; 不支持在单个语句中更新同一行两次。这种语句的效果是不可预测的。如果只有一个修改发生了,但却不容易(有时也不可能)预测哪一个发生了修改。
  • WITH递归查询 通过声明RECURSIVE关键字,一个WITH查询可以引用它自己的输出。 递归WITH查询的通常形式如下: 1 non_recursive_term UNION [ALL] recursive_term 其中:UNION在合并集合时会执行去重操作,而UNION ALLL则直接将结果集合并、不执行去重;只有递归项能够包含对于查询自身输出的引用。 使用递归WITH时,必须确保查询的递归项最终不会返回元组,否则查询将无限循环。 使用表tree来存储下图中的所有节点信息: 表定义语句如下: 1 CREATE TABLE tree(id INT, parentid INT); 表中数据如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 INSERT INTO tree VALUES(1,0),(2,1),(3,1),(4,2),(5,2),(6,3),(7,3),(8,4),(9,4),(10,6),(11,6),(12,10); SELECT * FROM tree; id | parentid ----+---------- 1 | 0 2 | 1 3 | 1 4 | 2 5 | 2 6 | 3 7 | 3 8 | 4 9 | 4 10 | 6 11 | 6 12 | 10 (12 rows) 通过以下WITH RECURSIVE语句,可以返回从顶层1号节点开始,整个树的节点,以及层次信息: 1 2 3 4 5 6 7 8 9 10 11 WITH RECURSIVE nodeset AS ( -- recursive initializing query SELECT id, parentid, 1 AS level FROM tree WHERE id = 1 UNION ALL -- recursive join query SELECT tree.id, tree.parentid, level + 1 FROM tree, nodeset WHERE tree.parentid = nodeset.id ) SELECT * FROM nodeset ORDER BY id; 上述查询中,我们可以看出,一个典型的WITH RECURSIVE表达式包含至少一个递归查询的CTE,该CTE中的定义为一个UNION ALL集合操作,第一个分支为递归起始查询,第二个分支为递归关联查询,需要自引用第一部分进行不断递归关联。该语句执行时,递归起始查询执行一次,关联查询执行若干次并将结果叠加到起始查询结果集中,直到某一些关联查询结果为空,则返回。 上述查询的执行结果如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 id | parentid | level ----+----------+------- 1 | 0 | 1 2 | 1 | 2 3 | 1 | 2 4 | 2 | 3 5 | 2 | 3 6 | 3 | 3 7 | 3 | 3 8 | 4 | 4 9 | 4 | 4 10 | 6 | 4 11 | 6 | 4 12 | 10 | 5 (12 rows) 从返回结果可以看出,起始查询结果包含level=1的结果集,关联查询执行了五次,前四次分别输出level=2,3,4,5的结果集,在第五次执行时,由于没有parentid和输出结果集id相等的记录,也就是再没有多余的孩子节点,因此查询结束。 对于WITH RECURSIVE表达式,GaussDB(DWS)支持其分布式执行。由于WITH RECURSIVE涉及到循环运算,GaussDB(DWS)引入了参数max_recursive_times,用于控制WITH RECURSIVE的最大循环次数,默认值为200,超过该次数则报错。
  • WITH递归查询 通过声明RECURSIVE关键字,一个WITH查询可以引用它自己的输出。 递归WITH查询的通常形式如下: 1 non_recursive_term UNION [ALL] recursive_term 其中:UNION在合并集合时会执行去重操作,而UNION ALLL则直接将结果集合并、不执行去重;只有递归项能够包含对于查询自身输出的引用。 使用递归WITH时,必须确保查询的递归项最终不会返回元组,否则查询将无限循环。 使用表tree来存储下图中的所有节点信息: 表定义语句如下: 1 CREATE TABLE tree(id INT, parentid INT); 表中数据如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 INSERT INTO tree VALUES(1,0),(2,1),(3,1),(4,2),(5,2),(6,3),(7,3),(8,4),(9,4),(10,6),(11,6),(12,10); SELECT * FROM tree; id | parentid ----+---------- 1 | 0 2 | 1 3 | 1 4 | 2 5 | 2 6 | 3 7 | 3 8 | 4 9 | 4 10 | 6 11 | 6 12 | 10 (12 rows) 通过以下WITH RECURSIVE语句,我们可以返回从顶层1号节点开始,整个树的节点,以及层次信息: 1 2 3 4 5 6 7 8 9 10 11 WITH RECURSIVE nodeset AS ( -- recursive initializing query SELECT id, parentid, 1 AS level FROM tree WHERE id = 1 UNION ALL -- recursive join query SELECT tree.id, tree.parentid, level + 1 FROM tree, nodeset WHERE tree.parentid = nodeset.id ) SELECT * FROM nodeset ORDER BY id; 上述查询中,我们可以看出,一个典型的WITH RECURSIVE表达式包含至少一个递归查询的CTE,该CTE中的定义为一个UNION ALL集合操作,第一个分支为递归起始查询,第二个分支为递归关联查询,需要自引用第一部分进行不断递归关联。该语句执行时,递归起始查询执行一次,关联查询执行若干次并将结果叠加到起始查询结果集中,直到某一些关联查询结果为空,则返回。 上述查询的执行结果如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 id | parentid | level ----+----------+------- 1 | 0 | 1 2 | 1 | 2 3 | 1 | 2 4 | 2 | 3 5 | 2 | 3 6 | 3 | 3 7 | 3 | 3 8 | 4 | 4 9 | 4 | 4 10 | 6 | 4 11 | 6 | 4 12 | 10 | 5 (12 rows) 从返回结果可以看出,起始查询结果包含level=1的结果集,关联查询执行了五次,前四次分别输出level=2,3,4,5的结果集,在第五次执行时,由于没有parentid和输出结果集id相等的记录,也就是再没有多余的孩子节点,因此查询结束。 对于WITH RECURSIVE表达式,GaussDB(DWS)支持其分布式执行。由于WITH RECURSIVE涉及到循环运算,GaussDB(DWS)引入了参数max_recursive_times,用于控制WITH RECURSIVE的最大循环次数,默认值为200,超过该次数则报错。
  • WITH中的数据修改语句 在WITH子句中使用数据修改命令INSERT、UPDATE、DELETE。这允许用户在同一个查询中执行多个不同操作。示例如下所示: 1 2 3 4 5 6 WITH moved_tree AS ( DELETE FROM tree WHERE parentid = 4 RETURNING * ) INSERT INTO tree_log SELECT * FROM moved_tree; 上述查询示例实际上从tree把行移动到tree_log。WITH中的DELETE删除来自tree的指定行,以它的RETURNING子句返回它们的内容,并且接着主查询读该输出并将它插入到tree_log。 WITH子句中的数据修改语句必须有RETURNING子句,用来返回RETURNING子句的输出,而不是数据修改语句的目标表,RETURNING子句形成了可以被查询的其余部分引用的临时表。如果一个WITH中的数据修改语句缺少一个RETURNING子句,则它形不成临时表并且不能在剩余的查询中被引用。 如果声明了RECURSIVE关键字,则不允许在数据修改语句中进行递归自引用。在某些情况中可以通过引用递归WITH的输出来绕过这个限制,例如: 1 2 3 4 5 6 7 8 9 WITH RECURSIVE included_parts(sub_part, part) AS ( SELECT sub_part, part FROM parts WHERE part = 'our_product' UNION ALL SELECT p.sub_part, p.part FROM included_parts pr, parts p WHERE p.part = pr.sub_part ) DELETE FROM parts WHERE part IN (SELECT part FROM included_parts); 这个查询将会移除一个产品的所有直接或间接子部件。 WITH子句中的子语句与主查询同时执行。因此,在使用WITH中的数据修改语句时,指定更新的顺序实际是以不可预测的方式发生的。所有的语句都使用同一个快照中执行,语句的效果在目标表上不可见。这减轻了行更新的实际顺序的不可预见性的影响,并且意味着RETURNING数据是在不同WITH子语句和主查询之间传达改变的唯一方法。 本示例中外层SELECT可以返回更新之前的数据: 1 2 3 4 WITH t AS ( UPDATE tree SET id = id + 1 RETURNING * ) SELECT * FROM tree; 本示例中外部SELECT将返回更新过的数据: 1 2 3 4 WITH t AS ( UPDATE tree SET id = id + 1 RETURNING * ) SELECT * FROM t; 不支持在单个语句中更新同一行两次。这种语句的效果是不可预测的。如果只有一个修改发生了,但却不容易(有时也不可能)预测哪一个发生了修改。