云服务器内容精选
-
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。 WIYH子句中的数据修改语句必须有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集合操作,第一个分支为递归起始查询,第二个分支为递归关联查询,需要自引用第一部分进行不断递归关联。该语句执行时,递归起始查询执行一次,关联查询执行若干次并将结果叠加到起始查询结果集中,直到某一些关联查询结果为空,则返回。 上述查询的执行结果如下: 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,超过该次数则报错。
-
连接类型介绍 通过SQL完成各种复杂的查询,多表之间的连接是必不可少的。连接分为:内连接和外连接两大类,每大类中还可进行细分。 内连接:标准内连接(INNER JOIN),交叉连接(CROSS JOIN)和自然连接(NATURAL JOIN)。 外连接:左外连接(LEFT OUTER JOIN),右外连接(RIGHT OUTER JOIN)和全外连接(FULL JOIN)。 为了能更好的说明各种连接之间的区别,下面通过具体示例进行详细的阐述。 创建示例表student和math_score,并插入数据,设置enable_fast_query_shipping为off(默认为on)即查询优化器使用分布式框架;参数explain_perf_mode为pretty(默认值为pretty)指定explain的显示格式。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 CREATE TABLE student( id INTEGER, name varchar(50) ); CREATE TABLE math_score( id INTEGER, score INTEGER ); INSERT INTO student VALUES(1, 'Tom'); INSERT INTO student VALUES(2, 'Lily'); INSERT INTO student VALUES(3, 'Tina'); INSERT INTO student VALUES(4, 'Perry'); INSERT INTO math_score VALUES(1, 80); INSERT INTO math_score VALUES(2, 75); INSERT INTO math_score VALUES(4, 95); INSERT INTO math_score VALUES(6, NULL); SET enable_fast_query_shipping = off; SET explain_perf_mode = pretty;
-
多表查询中on条件和where条件的区别 从上面各种连接语法中可见,除自然连接和交叉连接外,其他都需要有on条件(using在查询解析过程中会被转为on条件)来限制两表连接的结果。通常在查询的语句中也都会有where条件限制查询结果。这里说的on连接条件和where过滤条件是指不含可以下推到表上的过滤条件。on和where的区别是: on条件是两表连接的约束条件。 where是对两表连接后产生的结果集再次进行过滤。 简单总结就是:on条件优先于where条件,在两表进行连接时被应用;生成两表连接结果集后,再应用where条件。
-
示例 创建学生信息表student(ID、姓名、性别、学校)。 1 2 3 4 5 6 7 SET current_schema=public; DROP TABLE IF EXISTS student; CREATE table student( sId VARCHAR(10) NOT NULL , sname VARCHAR(10) NOT NULL , ssex VARCHAR(10) NOT NULl , sschool VARCHAR(10) NOT NULl ); 给表student插入数据。 1 2 3 4 5 6 7 8 INSERT INTO student VALUES('s01' , '赵雷' , '男', 'NENU'); INSERT INTO student VALUES('s02' , '钱电' , '男', 'SJTU'); INSERT INTO student VALUES('s03' , '孙风' , '男', 'Tongji'); INSERT INTO student VALUES('s04' , '李云' , '男', 'CCOM'); INSERT INTO student VALUES('s05' , '周梅' , '女', 'FuDan'); INSERT INTO student VALUES('s06' , '吴兰' , '女', 'WHU'); INSERT INTO student VALUES('s07' , '郑竹' , '女', 'NWAFU'); INSERT INTO student VALUES('s08' , '张三' , '女', 'Tongji'); 查看表student。 1 SELECT * FROM student; 回显如下: 创建教师信息表teacher(ID、姓名、性别、学校)。 1 2 3 4 5 6 DROP TABLE IF EXISTS teacher; CREATE table teacher( tid VARCHAR(10) NOT NULL , tname VARCHAR(10) NOT NULL , tsex VARCHAR(10) NOT NULL , tschool VARCHAR(10) NOT NULL ); 给表teacher插入数据。 1 2 3 INSERT INTO teacher VALUES('t01' , '张磊', '男', 'FuDan'); INSERT INTO teacher VALUES('t02' , '李强', '男', 'WHU'); INSERT INTO teacher VALUES('t03' , '王刚', '男', 'Tongji'); 查询表teacher。 1 SELECT * FROM teacher; 使用UNION(合并且去重)获取学生和教师所在学校,并按学校名称首字母升序排序。 1 2 3 4 5 6 7 8 SELECT t.school FROM ( SELECT sschool AS school FROM student UNION SELECT tschool AS school FROM teacher ) t ORDER BY t.school ASC; 回显如下: 使用UNION ALL(合并不去重)获取所有学生和教师所在学校,并按学校名称首字母升序排序。 1 2 3 4 5 6 7 8 SELECT t.school FROM ( SELECT sschool AS school FROM student UNION ALL SELECT tschool AS school FROM teacher ) t ORDER BY t.school ASC; 使用UNION ALL(合并带有WHERE子句SQL结果集)获取来自'Tongji'的学生和教师的所有信息,并按学生和教师的编号升序排序。 1 2 3 4 5 6 7 8 9 10 SELECT t.* FROM ( SELECT Sid AS id ,Sname AS name ,Ssex AS sex ,Sschool AS school FROM student WHERE Sschool='Tongji' UNION ALL SELECT Tid AS id ,Tname AS name ,Tsex AS sex ,Tschool AS school FROM teacher WHERE Tschool='Tongji' ) t ORDER BY t.id ASC;
-
限制结果查询数量 如果需要查询只返回部分结果,可以使用LIMIT语句限制查询结果返回的记录数。 1 2 3 4 5 6 7 8 9 SELECT product_id,product_name,category,quantity FROM newproducts ORDER BY quantity DESC limit 5; product_id | product_name | category | quantity ------------+--------------+-------------+---------- 3577 | dumbbell | sports | 550 2344 | milklotion | skin care | 320 1666 | Frisbee | toys | 244 1210 | necklace | jewels | 200 1502 | earphones | electronics | 150 (5 rows)
-
聚合查询 可以通过使用GROUP BY语句配合聚合函数,构建一个聚合查询来关注数据的整体情况。 1 2 3 4 5 6 7 8 9 SELECT category, string_agg(quantity,',') FROM newproducts group by category; category | string_agg -------------+------------ toys | 80,244 books | 100 sports | 550 jewels | 200 skin care | 320 electronics | 150
-
对结果进行筛选 通过WHERE语句对查询的结果进行过滤,找到想要查询的部分。 1 2 3 4 5 6 SELECT * FROM newproducts WHERE category='toys'; product_id | product_name | category | quantity ------------+--------------+----------+---------- 1601 | telescope | toys | 80 1666 | Frisbee | toys | 244 (2 rows)
-
对结果进行排序 使用ORDER BY语句可以让查询结果按照期望的方式进行排序。 1 2 3 4 5 6 7 8 9 10 11 SELECT product_id,product_name,category,quantity FROM newproducts ORDER BY quantity DESC; product_id | product_name | category | quantity ------------+--------------+-------------+---------- 3577 | dumbbell | sports | 550 2344 | milklotion | skin care | 320 1666 | Frisbee | toys | 244 1210 | necklace | jewels | 200 1502 | earphones | electronics | 150 1700 | interface | books | 100 1601 | telescope | toys | 80 (7 rows)
更多精彩内容
CDN加速
GaussDB
文字转换成语音
免费的服务器
如何创建网站
域名网站购买
私有云桌面
云主机哪个好
域名怎么备案
手机云电脑
SSL证书申请
云点播服务器
免费OCR是什么
电脑云桌面
域名备案怎么弄
语音转文字
文字图片识别
云桌面是什么
网址安全检测
网站建设搭建
国外CDN加速
SSL免费证书申请
短信批量发送
图片OCR识别
云数据库MySQL
个人域名购买
录音转文字
扫描图片识别文字
OCR图片识别
行驶证识别
虚拟电话号码
电话呼叫中心软件
怎么制作一个网站
Email注册网站
华为VNC
图像文字识别
企业网站制作
个人网站搭建
华为云计算
免费租用云托管
云桌面云服务器
ocr文字识别免费版
HTTPS证书申请
图片文字识别转换
国外域名注册商
使用免费虚拟主机
云电脑主机多少钱
鲲鹏云手机
短信验证码平台
OCR图片文字识别
SSL证书是什么
申请企业邮箱步骤
免费的企业用邮箱
云免流搭建教程
域名价格