如何获得分层树的所有行的结束和起点?

时间:2018-04-27 12:27:05

标签: sql sqlite

我有一个SQLite数据库,有一个不同层次树的工作台(类似于下图),我只想得到每个树线的起点和终点。 enter image description here 蓝色是树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不是预期的),哪个是该行的最后一个点。其他值列不相关。

这是我的预期结果:
enter image description here

到目前为止我们尝试过的是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;

您是否有任何想法如何改进代码甚至更好的想法?我们有时只得到回报,结果似乎并非总是如此。

1 个答案:

答案 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);