PostgreSql递归包含层级level

当在用oracle做递归时,往往会用到一个虚列level,表示当前的节点是第几层,现在PostgreSql的递归语法中(with recursive)中不包含层级列,当然你安装了PostgreSql的扩展也是可以的,就是安装cross这个脚本,具体在postgreSql安装目录项的share/extension下的tablefunc.sql,脚本。

由于在我实际的项目中不允许安装哪些脚本,因此只能先自定义一个函数,具体代码如下:

首先,创建自定义类型

CREATE TYPE public.type_custom_recursive AS (
  keyid TEXT,
  branch TEXT,
  parent_keyid TEXT,
  level TEXT
);

再创建函数:

CREATE OR REPLACE FUNCTION public.custom_recursive (
  table_name varchar,
  keyid text,
  parent_keyid text,
  keyid_value text,
  level integer,
  split_value varchar
)
RETURNS SETOF public.type_custom_recursive AS
$body$
declare
test_ type_custom_recursive;
    sql_text VARCHAR(1000);


BEGIN
-- i_id  as keyid,id as branch,level as level 
if $5 = 0 THEN
sql_text := 'select i_id::text as keyid,id::text as branch,i_parent_id::text as parent_keyid,level::text as level from (  
          with recursive temp as(
          select '||$2||' as i_id,'||$2||'::text as id ,'||$3||' from '|| $1 ||' where '||$2||' = cast('||$4||
          'as int) union all
          select b.'||$2||',cast (a.id || '''||split_value||''' || b.'||$2||' as text) as id,b.'||$3||'  from temp a,'||$1||' b
          where a.'||$2||' = b.'||$3||')select i_id,id,f_char_in_string(id,'''||$6||''')+1 as level,i_parent_id from temp
          ) t order by i_id';
          
else
sql_text := 'select i_id::text as keyid,id::text as branch,i_parent_id::text as parent_keyid,level::text as level from (  
          with recursive temp as(
          select '||$2||' as i_id,'||$2||'::text as id ,'||$3||' from '|| $1 ||' where '||$2||' = cast('||$4||
          'as int) union all
          select b.'||$2||',cast (a.id || '''||split_value||''' || b.'||$2||' as text) as id,b.'||$3||'  from temp a,'||$1||' b
          where a.'||$2||' = b.'||$3||')select i_id,id,f_char_in_string(id,'''||$6||''')+1 as level,i_parent_id from temp
          ) t  where level = '|| $5 ||' order by i_id';          
end if;


 for test_ in execute sql_text loop
          return next test_;
  end loop;          
end;
$body$
LANGUAGE 'plpgsql'
;

说明:

table_name varchar ,--需要递归的表名
  keyid text,--id
  parent_keyid text,--父id
  keyid_value text,--id的值
  level integer,--层级 0的话显示当前id下的所有节点
  split_value varchar --  分隔符比如"->"

注意这里的id默认都是为整型的,如果id是varchar型那么需要稍作修改的。

下面做个小例:

select * from custom_recursive('organization','i_id','i_parent_id','1',0,'->');

输出为

keyid,branch,parentkeyid,level

1 ,1,null,1

2,1->2,1,2

3,1->3,1,2

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PostgreSQL递归语法使用的是WITH RECURSIVE关键字。具体语法如下: ``` WITH RECURSIVE cte_name AS ( -- 初始查询语句 SELECT initial_query AS col1, initial_query AS col2 UNION ALL -- 递归查询语句 SELECT recursive_query AS col1, recursive_query AS col2 FROM cte_name WHERE condition ) SELECT * FROM cte_name; ``` 其中,cte_name为递归查询的名称,initial_query为初始查询语句,recursive_query为递归查询语句,condition为递归终止条件。 在递归查询中,初始查询语句会先执行一次,然后根据递归查询语句和递归终止条件进行递归查询,直到满足递归终止条件为止。 需要注意的是,递归查询语句中必须包含一个或多个UNION ALL操作符,且UNION ALL前后查询结果的列数和数据类型必须一致。 ### 回答2: PostgreSQL 是一个功能强大的开源关系型数据库系统,它提供了递归查询功能,让我们能够在举例时处理具有递归结构的数据。 在 PostgreSQL 中,递归查询可以使用 WITH RECURSIVE 语法来实现。递归查询的基本语法如下: WITH RECURSIVE 递归视图名 (递归视图的列名列表) AS ( 非递归查询表达式 UNION [ALL] 递归查询表达式 ) SELECT 查询语句 FROM 递归视图名 [WHERE 条件] [ORDER BY 排序依据] 其中,递归视图名是指递归查询生成的临时表的名称。递归视图的列名列表是指在递归视图中定义的列的名称。非递归查询表达式是指递归查询的初始查询,用于生成初始的结果集。UNION ALL 是可选的修饰符,用于指定是否包括重复行。递归查询表达式是指递归查询的自引用,用于生成新的结果集并与之前的结果集合并。查询语句是指最终对递归视图进行查询的语句。WHERE 和 ORDER BY 子句是可选的,用于进一步过滤和排序结果。 递归查询通常需要定义递归终止条件,以避免无限循环。递归终止条件通常通过在递归查询表达式中添加一个条件来实现,当该条件不满足时,递归查询就会结束。 递归查询的一个常见应用是处理具有递归结构的数据,例如组织机构、树形结构等。通过使用递归查询,我们可以轻松地遍历整个结构、查找特定节点、计算路径长度等。 总之,PostgreSQL递归语法提供了一种方便处理具有递归结构的数据的方法。通过使用 WITH RECURSIVE 语句和递归终止条件,我们可以编写复杂的递归查询来解决各种问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值