我有一个SQLite数据库,有一个不同层次树的工作台(类似于下图),我只想得到每个树线的起点和终点。 蓝色是树ID(称为ws_id),绿色是想要的起点和终点,而红色是开始和之间不需要的对象终点。
这里的数据示例与上面的分层树具有相同的结构,并且具有与我相似的数据结构:
CREATE TABLE feat_link
(ws_id integer, source_node varchar(10), target_node varchar(10));
ALTER TABLE feat_link ADD PRIMARY KEY (ws_id);
INSERT INTO feat_link
VALUES ('b', '1', '36');
INSERT INTO feat_link
VALUES ('b', '1', '17');
INSERT INTO feat_link
VALUES ('b', '36', '21');
INSERT INTO feat_link
VALUES ('b', '2', '20');
INSERT INTO feat_link
VALUES ('b', '3', '37');
INSERT INTO feat_link
VALUES ('b', '37', '24');
如您所见,source_node值仅与下一个target_node值匹配,而不与树线的最终节点匹配。我需要的是匹配(我认为是递归查询),首先要识别哪个source_nodes实际上是树的beginninig(注意,例如B不是预期的),哪个是该行的最后一个点。其他值列不相关。
到目前为止我们尝试过的是RECURSIVE查询。这里假设我的数据表被称为" feat_link":
WITH RECURSIVE target(x) AS (
SELECT (select 1 from feat_link)
UNION ALL
SELECT feat_link.target_node
FROM feat_link, target
WHERE feat_link.source_node=target.x
AND feat_link.source_node IS NOT NULL
and feat_link.ws_id = 'B'
)
select distinct x from target;
您是否有任何想法如何改进代码甚至更好的想法?我们有时只得到回报,结果似乎并非总是如此。
答案 0 :(得分:0)
首先,以标准方式枚举所有可能的行(有用和无用):
WITH RECURSIVE lines(ws_id, source_node, target_node) AS (
-- start with all nodes that have no link to their start
SELECT ws_id, source_node, target_node
FROM feat_link
WHERE (ws_id, source_node) NOT IN (SELECT ws_id, target_node
FROM feat_link)
UNION ALL
SELECT l.ws_id, l.source_node, f.target_node
FROM feat_link f
JOIN lines l ON (f.ws_id, f.source_node) = (l.ws_id, l.target_node)
)
...
然后过滤掉所有属于较长行的行,即从其末尾有链接的行:
...
SELECT *
FROM lines
WHERE (ws_id, target_node) NOT IN (SELECT ws_id, source_node
FROM feat_link);