Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL递归CTE百万大小树的动态排序分页选择_Postgresql_Recursion_Tree_Recursive Query - Fatal编程技术网

PostgreSQL递归CTE百万大小树的动态排序分页选择

PostgreSQL递归CTE百万大小树的动态排序分页选择,postgresql,recursion,tree,recursive-query,Postgresql,Recursion,Tree,Recursive Query,我的目标是创建一个查询,通过控制每个深度返回的项目的深度和数量(按排名降序排序,排名经常变化),我可以在其中检索树 即 给我从节点id 4开始的树,最大深度为5,从该节点开始,每个级别最多有5个子节点,按秩降序排列 所以我有一个树形结构: CREATE TABLE thingtree ( id uuid NOT NULL, parent_id uuid, text character varying(2048) NOT NULL, rank integer NOT NULL DE

我的目标是创建一个查询,通过控制每个深度返回的项目的深度和数量(按排名降序排序,排名经常变化),我可以在其中检索树

给我从节点id 4开始的树,最大深度为5,从该节点开始,每个级别最多有5个子节点,按秩降序排列

所以我有一个树形结构:

CREATE TABLE thingtree
(
  id uuid NOT NULL,
  parent_id uuid,
  text character varying(2048) NOT NULL,
  rank integer NOT NULL DEFAULT 0,
  CONSTRAINT thingtree_pkey PRIMARY KEY (id),
  CONSTRAINT thingtree_parent_id_fkey FOREIGN KEY (parent_id)
      REFERENCES thingtree (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
我想按id选择一个节点,然后获取它的所有子节点,每个深度都有一个可配置的记录限制,并按等级排序,这是经常变化的

所以我决定创建一些数据:

CREATE EXTENSION "uuid-ossp";
CREATE FUNCTION build_tree (parent_id uuid,max_depth integer,current_depth integer,max_direct_children integer) RETURNS boolean AS $$
   DECLARE
    new_id uuid := uuid_generate_v4();
    BEGIN

    IF current_depth >= max_depth THEN
        RETURN 0;
    END IF;

    insert into thingtree VALUES (new_id, parent_id,'test',current_depth + 1);
    FOR i IN 0..(max_direct_children - 1) LOOP
        PERFORM build_tree(new_id,max_depth,current_depth + 1, max_direct_children);
    END LOOP;


    RETURN 0;   
    END;
$$ LANGUAGE plpgsql;
然后我使用这个函数生成一个5层的树,每个层有6个子层

select build_tree(NULL ,5, 0 ,6);
运行上述功能可能需要约20秒

接下来,我尝试递归地选择数据:

WITH RECURSIVE thingtrees AS (
    SELECT tt.id,1::INT AS depth, tt.parent_id, tt.text, tt.rank FROM thingtree as tt WHERE id = '207f7c55-1c68-4f0e-9493-416b84b6a0a4'
  UNION ALL
    SELECT st.id, tts.depth + 1 AS depth, st.parent_id, st.text, st.rank
    FROM 
    thingtrees as tts
    JOIN 
    thingtree st 
    on (tts.id = st.parent_id)
    WHERE tts.depth <= 5 order by st.rank

  )
SELECT *
FROM thingtrees
现在深度很好,它知道不能超过5,但问题是我只希望树中每个节点级别最多有5个直接子节点,但结果返回6,因为我没有限制它

问题是如果我从CTE限制递归联合:

WITH RECURSIVE thingtrees AS (
    SELECT tt.id,1::INT AS depth, tt.parent_id, tt.text, tt.rank FROM thingtree as tt WHERE id = '207f7c55-1c68-4f0e-9493-416b84b6a0a4'
  UNION ALL
    (SELECT st.id, tts.depth + 1 AS depth, st.parent_id, st.text, st.rank
    FROM 
    thingtrees as tts
    JOIN 
    thingtree st 
    on (tts.id = st.parent_id)
    WHERE tts.depth <= 5 order by st.rank limit 5)

  )
SELECT *
FROM thingtrees

这里的问题是它只返回树的前5个子节点,而不是每个深度的5个子节点。

复制了您的示例,并从每个深度获得了21行5个子节点。这不是人们所期望的吗?您确定手动提供的id是根节点吗?序列仍处于关闭状态,order by st.rank仅按秩排序整个深度。