使用 H2 DB 和 SQL 递归拆分路径

Recursive split of path with H2 DB and SQL

我有以下常见形式的路径名(路径深度不限):

/a/b/c/d/e/...

例子

/a/b/c/d/e

预期结果

我现在想要实现的是将路径拆分为 table 包含文件夹和各自的父级:

parent folder
/a/b/c/d/ e
/a/b/c/ d
/a/b/ c
/a/ b
/ a

H2 db 的能力在拆分字符串时有点受限,因此我的假设是它必须递归解决(特别是因为路径深度不受限制)。

任何帮助将不胜感激:)

做这样的事情:

with recursive 
  p(p) as (select '/a/b/c/d/e' as p),
  t(path, parent, folder, i) as (
    select 
      p, 
      REGEXP_REPLACE(p, '(.*)/\w+', ''),
      REGEXP_REPLACE(p, '.*/(\w+)', ''), 
      1 
    from p
    union
    select 
      t.parent, 
      REGEXP_REPLACE(t.parent, '(.*)/\w+', ''),
      REGEXP_REPLACE(t.parent, '.*/(\w+)', ''), 
      t.i + 1
    from t
    where t.parent != ''
  )
select *
from t;

导致

|PATH      |PARENT  |FOLDER|I  |
|----------|--------|------|---|
|/a/b/c/d/e|/a/b/c/d|e     |1  |
|/a/b/c/d  |/a/b/c  |d     |2  |
|/a/b/c    |/a/b    |c     |3  |
|/a/b      |/a      |b     |4  |
|/a        |        |a     |5  |

不确定您是否真的对尾随 / 个字符感兴趣,但您可以根据需要轻松修复查询。

您需要使用递归查询,例如:

WITH RECURSIVE CTE(S, F, T) AS (
SELECT '/a/b/c/d/e', 0, 1
UNION ALL
SELECT S, T, LOCATE('/', S, T + 1)
FROM CTE
WHERE T <> 0
)
SELECT
    SUBSTRING(S FROM 1 FOR F) PARENT,
    SUBSTRING(S FROM F + 1 FOR
        CASE T WHEN 0 THEN CHARACTER_LENGTH(S) ELSE T - F - 1 END) FOLDER
FROM CTE WHERE F > 0;

它产生

PARENT FOLDER
/ a
/a/ b
/a/b/ c
/a/b/c/ d
/a/b/c/d/ e