我的编程空间,编程开发者的网络收藏夹
学习永远不晚

PostgreSQL DBA(35) - CTE

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

PostgreSQL DBA(35) - CTE

CTE(Common Table Expressions)是指使用WITH语句定义的通用表表达式。
如:



testdb=# explain verbose WITH t1 AS ( SELECT * FROM t_w1 WHERE t_w1.id % 4 = 0 ) SELECT * FROM t1 JOIN t_w2 as t2 ON t2.id = t1.id;
                                QUERY PLAN                                
--------------------------------------------------------------------------
 Hash Join  (cost=167.74..359.00 rows=76 width=70)
   Output: t1.id, t1.c1, t2.id, t2.c1
   Hash Cond: (t2.id = t1.id)
   CTE t1
     ->  Seq Scan on public.t_w1  (cost=0.00..166.50 rows=38 width=8)
           Output: t_w1.id, t_w1.c1
           Filter: ((t_w1.id % 4) = 0)
   ->  Seq Scan on public.t_w2 t2  (cost=0.00..153.00 rows=10000 width=8)
         Output: t2.id, t2.c1
   ->  Hash  (cost=0.76..0.76 rows=38 width=62)
         Output: t1.id, t1.c1
         ->  CTE Scan on t1  (cost=0.00..0.76 rows=38 width=62)
               Output: t1.id, t1.c1
(13 rows)

使用CTE可以:
1.增强SQL的可读性:如上例所示,通过CTE,可以”模块化”SQL语句,增强脚本可读性
2.实现递归:通过增加RECURSIVE修饰符来引入它自己,从而实现递归

递归
递归通常用于处理逻辑上存在层次或树状结构的数据.
如:



drop table if exists t_cte;
create table t_cte(id varchar(10),parent_id varchar(10));
insert into t_cte values('1',NULL);
insert into t_cte values('11','1');
insert into t_cte values('12','1');
insert into t_cte values('111','11');
insert into t_cte values('112','11');
insert into t_cte values('121','12');

id为数据表的id,parent_id是该id的父id,通过该字段可找到对应的父记录,先要求打印这些数据的树状结构,相应的SQL语句如下:



WITH RECURSIVE ret AS
(
  SELECT
    parent_id,
    id::text as name,
    id::text
  FROM  t_cte
  WHERE id = '1'
  UNION ALL
  SELECT
    t.parent_id,
    t.parent_id || ' > ' || t.id as name,
  t.id
  FROM ret
  JOIN t_cte t
  ON t.parent_id = ret.id
)
SELECT
  parent_id,
  name 
FROM ret;

WITH RECURSIVE语句包含两个部分
1.non-recursive term(非递归部分)
即上例中的:



SELECT
    parent_id,
    id::text as name,
    id::text
  FROM  t_cte
  WHERE id = '1'

2.recursive term(递归部分)
即上例中的:



SELECT
    t.parent_id,
    t.parent_id || ' > ' || t.id as name,
  t.id
  FROM ret
  JOIN t_cte t
  ON t.parent_id = ret.id

执行步骤如下
1.执行non-recursive term。其结果作为recursive term中对ret的引用,同时将这部分结果放入工作表中
2.重复执行如下步骤,直到工作表为空:用工作表的内容替换递归的自引用(上例中的ret),执行recursive term,并用该结果替换工作表

大凡递归, 必须有结束条件,工作表为空则是CTE Recursive的结束条件.就上例来说,



SELECT
    t.parent_id,
    t.parent_id || ' > ' || t.id as name,
  t.id
  FROM ret
  JOIN t_cte t
  ON t.parent_id = ret.id

返回为空时,递归结束.

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

PostgreSQL DBA(35) - CTE

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

目录