如何编写循环条件以在 postgresql 中获取子文件夹名称

问题描述

我正在尝试获取文件夹中的文件名称

示例:

folder_id  folder_name parent_folder_id
      1             F1      0
      2             F2      1
      3             F3      2
      4             F4      3

现在我正在尝试获取 f4 名称以及父文件名称,例如:F1/F2/F3/F4 我根据folder_id获取parent_folder_id并写出循环条件,这是我的函数

for vrecord in (select parent_folder_id from public."VOfficeApp_filefolder"
                  where folder_id = ip_folder_id)
loop        
            
       return query
      select (SELECT array_to_json(array_agg(row_to_json(b))) FROM
             (select folder_name from public."VOfficeApp_filefolder"
                  where folder_id = v_id)b)as path;
    

结束循环;

解决方法

聚合函数不构建分层结果;为此,您需要一个 RECURSIVE CTE。构建层次结构后,您可以转换为 json。下面的函数就是这样做的。该函数采用您感兴趣的文件夹名称,毕竟它只使用了 at the last minuet 来消除构建的其余层次结构。

create or replace function path_to_folder(target_folder_name text) 
  returns json
 language sql 
as $$ 
    with recursive folder_path (id,folder_name,path) as 
         ( select folder_id,folder_name || '/' 
             from folders
            where parent_folder_id = 0
            union all
            select f.folder_id,f.folder_name,fp.path || f.folder_name || '/' 
              from folders f 
              join folder_path fp on (f.parent_folder_id = fp.id)
         ),bjc (folder_name,path) as 
         ( select folder_name,path 
             from folder_path 
            where folder_name = target_folder_name
         ) -- select * from bjc; 
    select json_agg(row_to_json((folder_name,path)))
      from bjc
     group by folder_name; 
$$;         

注意:可能不需要第二个 cte bjc(在 Json 转换之前),但因为我讨厌 json(恕我直言,我宁愿不处理这种复杂性)。您可以将 where 子句从中移动到 json 结构中。但我总是喜欢在转换之前先看看结果。

旁注:
Postgres 9.2 已过时。已于 2017 年 11 月停止支持。您应该认真更新。