首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sqlite递归祖先查询

问sqlite递归祖先查询
EN

Stack Overflow用户
提问于 2017-12-13 14:43:13
回答 3查看 1.5K关注 0票数 6

我正在尝试弄清楚如何在分层表中使用递归查询。我需要获取给定记录的祖先,并且这些记录应该按照它们在层次结构中的级别排序。也就是说,第一条记录应该是顶级节点,下一条记录应该是一个子节点,然后是它的子节点,一直到被查询的记录。

考虑一个名为"food“的表,其中包含以下数据。这是一个简单的层次结构,除了顶部的记录之外,每个记录都有一个父记录。

代码语言:javascript
复制
id         | parent
-----------+---------
top        |
fruit      | top
red        | fruit
cherry     | red
apple      | red
orange     | fruit
clementine | orange
mandarin   | orange

为了理解关于这个主题的各种网页,我拼凑了下面的查询,它给出了" mandarin“记录的所有祖先,包括mandarin记录本身。

代码语言:javascript
复制
with recursive
    child_record(id) as (
        values('mandarin')

        union

        select parent
        from food, child_record
        where food.id = child_record.id
    )
select id from food
    where food.id in child_record;

但是,该查询返回记录的顺序在我看来是任意的:

代码语言:javascript
复制
fruit
mandarin
orange
top

我希望记录首先从最上面的记录开始排序,再从下到普通话记录。

代码语言:javascript
复制
top
fruit
orange
mandarin

如何构造查询以按所需顺序给出记录?

EN

回答 3

Stack Overflow用户

发布于 2017-12-14 02:42:04

我想我明白了?我不太愿意说我知道,因为我仍然不太理解语法,但是下面的查询产生了我想要的结果。

代码语言:javascript
复制
with recursive
    child_record(level, id) as (
        values(0, 'mandarin')

        union

        select child_record.level+1, food.parent
        from food, child_record
        where food.id = child_record.id
    )
select child_record.level, food.id
from  food, child_record
where food.id = child_record.id
order by child_record.level desc;
票数 4
EN

Stack Overflow用户

发布于 2017-12-13 16:20:35

我建议按rowid排序:

代码语言:javascript
复制
with recursive
    child_record(id) as (
        select 'mandarin'

        union

        select parent
        from food, child_record
        where food.id = child_record.id
    )
select id from food
    where food.id in child_record 
    order by food.rowid;
票数 1
EN

Stack Overflow用户

发布于 2021-06-17 22:00:30

通过将this answer和您的组合在一起,我发现了两个可能的加速(我还没有测量到):

  1. 是常规连接而不是交叉连接( query).
  2. union all的from food, child_record部分而不是union -结果已经过重复数据消除。

此外,我认为这个查询很自然地对其结果进行排序,但我重新添加了level字段以确保这一点。

代码语言:javascript
复制
with recursive ancestor(id, parent, level) as (
   select id, parent, 0
   from food
   where id = 'mandarin' -- this is the starting point you want in your recursion
   union all
   select f.id, f.parent, a.level + 1
   from food f
     join ancestor a on a.parent = f.id  -- this is the recursion
) 
select id
from ancestor
order by level;
代码语言:javascript
复制
┌──────────┐
│    id    │
├──────────┤
│ mandarin │
│ orange   │
│ fruit    │
│ top      │
└──────────┘
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47787048

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档