打破 Postgres 11 中的递归查询

Joh*_*son 5 postgresql postgresql-11

我在从树结构中获取正确的数据时遇到了一些麻烦,我只希望分支匹配条件中的第一个节点成为查询的结果。

我有这个域表:

create table domains(
    id bigint,
    domain_name varchar,
    parent_id bigint,
    valid boolean
)

insert into domains values
    (1, 'example.com', null, false),
    (2, 'a.example.com', 1, true),
    (3, 'b.example.com', 1, false),
    (4, 'c.b.example.com', 3, true),
    (5, 'd.a.example.com', 2, true)
Run Code Online (Sandbox Code Playgroud)

这给出了这棵树,其中有效域为绿色:

域图

基于此,我希望a.example.comc.b.example.com作为有效域返回。如果顶级域名example.com有效,则仅应返回该顶级域名。(“有效”只是其他地方确定的标志。)

我有一个递归查询来获取整个域树:

WITH RECURSIVE valid_domains AS (
  SELECT id, domain_name, valid FROM domains
  WHERE parent_id IS NULL

  UNION ALL

  SELECT d.id, d.domain_name, d.valid FROM domains d
  JOIN valid_domains vd ON d.parent_id = vd.id
)
SELECT * FROM valid_domains
Run Code Online (Sandbox Code Playgroud)

...但是我的绊脚石是弄清楚如何过滤有效域并在我点击有效域时打破该分支,而不返回其下面的任何有效域。

我研究过窗口函数,但到目前为止还无法将其与递归查询相结合。我首先进行递归是否采取了错误的方法?

Aki*_*ina 4

WITH RECURSIVE cte AS (
  SELECT id, domain_name, valid 
  FROM domains
  WHERE parent_id IS NULL
UNION ALL
  SELECT domains.id, domains.domain_name, domains.valid 
  FROM domains
  JOIN cte ON domains.parent_id = cte.id
  WHERE NOT cte.valid -- stop recursion when valid node reached
)

SELECT id, domain_name
FROM cte
WHERE valid
Run Code Online (Sandbox Code Playgroud)

小提琴