【问题标题】:Can I get ancestor element in a single query?我可以在单个查询中获取祖先元素吗?
【发布时间】:2013-10-08 17:58:29
【问题描述】:

假设我有一个名为“parent”的列,它引用同一个表中的 ID 列。 所以它可以为空或一个数字。如果为空,则表示该记录没有父记录。

例子:

ID  name  parent
1   A
2   B     1
3   C     2
4   D     2

为了得到 C 的祖先,我做了两个查询:

SELECT parent FROM table WHERE id = 2

SELECT parent FROM table WHERE id = 1

然后我得到空父,所以我知道 1 是祖先。

我想知道是否可以在单个查询中执行此操作:)

【问题讨论】:

标签: sql sqlite foreign-keys parent-child hierarchy


【解决方案1】:

我认为您不能在单个查询中完成,但使用 recursive_triggers (SQLite>=3.6.18) 您可以使用固定数量的语句来完成。

检查这个(tt 是你的表名):

-- Schema addition:
PRAGMA recursive_triggers=1;
CREATE TEMP TABLE ancid(id UNIQUE, ancestor);
CREATE TEMP TRIGGER ancid_t AFTER INSERT ON ancid WHEN (SELECT parent FROM tt WHERE id=NEW.ancestor) IS NOT NULL BEGIN
    INSERT OR REPLACE INTO ancid SELECT NEW.id, parent FROM tt WHERE id=NEW.ancestor;
END;

-- Getting ancestor from id=3:
INSERT INTO ancid VALUES(3, 3);
SELECT * FROM ancid WHERE id=3;

-- Getting all ancestors:
INSERT OR REPLACE INTO ancid SELECT id, id FROM tt;
SELECT * FROM ancid;

【讨论】:

  • 创建表和插入看起来非常昂贵:P
  • @AnnaK。是的!但是是普通的 SQLite。并且使用内存临时表,也许 SQLite 引擎比其他编程解决方案获得最好的性能......
【解决方案2】:

是的,有使用Recursive CTE

本质上是这样。这是伪代码,但它会让你达到 90%。如果你给我一些表定义,我可以为你做更多的事情

;with coolCTE as (
SELECT id,NAME,1 as level
FROM tableX
where parent is null
union all
select id,name,level + 1
from tablex as y 
inner join coolcte as c on y.id = c.parentid
where y.parentid is not null
)

【讨论】:

  • 请更改您的链接以指向相关的 SQLite 文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 2023-03-15
  • 2013-02-06
  • 2015-03-10
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多