如何查找没有子节点的树节点
How to find tree nodes that don't have child nodes
Firebird Db 将图表帐户记录存储在 table:
CREATE TABLE CHARTACC
(
ACCNTNUM Char(8) NOT NULL, -- Account ID (Primary Key)
ACCPARNT Char(8), -- Parent ID
ACCCOUNT Integer, -- account count
ACCORDER Integer, -- order of children in nodes
ACCTITLE varchar(150),
ACDESCRP varchar(4000),
DTCREATE timestamp -- date and time of creation
)
我必须编写查询,从 table 中仅选择没有子节点的最后一个节点 e.g.nodes (child2, child3, subchild1, subchild2, subchild3 和 subchild4).
您的查询需要像这样工作:
select * from CHARTACC where ACCNTNUM not in (select ACCPARNT from CHARTACC)
换句话说,此 table 中的 select 项在其父字段的同一 table 任何地方都找不到其标识符。
Jerry 建议的 not in
方法通常在 Interbase/Firebird/Yaffil/RedDatabase 系列中工作得相当慢,没有使用索引等。
另一种可能的表示方式也是如此Select X from T1 where
NOT EXISTS ( select * from t2 where t2.a = t1.b)
- 结果也可能非常慢。
我同意这些查询更好地代表了人类的需求,因此更具可读性,但仍然不推荐在 Firebird 上使用。我在 1990 年代做类似 Herbalife 的应用程序时被严重咬伤,我选择了这种包裹在循环中的请求来进行每月自下而上的计数 - update ... where not exists ...
- 每次迭代缩放为 o (n^2) 在 Interbase 5.5 中。诚然,Firebird 3 从那以后取得了长足的进步,但仍然不推荐这种 "direct" 方法。
更多 SQL-传统和 FB 友好的表达方式,尽管不那么直接且更难阅读,将是 Select t1.x from t1 LEFT JOIN t2 on t1.a=t2.b WHERE t2.y IS NULL
Firebird Db 将图表帐户记录存储在 table:
CREATE TABLE CHARTACC
(
ACCNTNUM Char(8) NOT NULL, -- Account ID (Primary Key)
ACCPARNT Char(8), -- Parent ID
ACCCOUNT Integer, -- account count
ACCORDER Integer, -- order of children in nodes
ACCTITLE varchar(150),
ACDESCRP varchar(4000),
DTCREATE timestamp -- date and time of creation
)
我必须编写查询,从 table 中仅选择没有子节点的最后一个节点 e.g.nodes (child2, child3, subchild1, subchild2, subchild3 和 subchild4).
您的查询需要像这样工作:
select * from CHARTACC where ACCNTNUM not in (select ACCPARNT from CHARTACC)
换句话说,此 table 中的 select 项在其父字段的同一 table 任何地方都找不到其标识符。
Jerry 建议的 not in
方法通常在 Interbase/Firebird/Yaffil/RedDatabase 系列中工作得相当慢,没有使用索引等。
另一种可能的表示方式也是如此Select X from T1 where
NOT EXISTS ( select * from t2 where t2.a = t1.b)
- 结果也可能非常慢。
我同意这些查询更好地代表了人类的需求,因此更具可读性,但仍然不推荐在 Firebird 上使用。我在 1990 年代做类似 Herbalife 的应用程序时被严重咬伤,我选择了这种包裹在循环中的请求来进行每月自下而上的计数 - update ... where not exists ...
- 每次迭代缩放为 o (n^2) 在 Interbase 5.5 中。诚然,Firebird 3 从那以后取得了长足的进步,但仍然不推荐这种 "direct" 方法。
更多 SQL-传统和 FB 友好的表达方式,尽管不那么直接且更难阅读,将是 Select t1.x from t1 LEFT JOIN t2 on t1.a=t2.b WHERE t2.y IS NULL