如何查找没有子节点的树节点

时间:2018-12-12 01:10:14

标签: sql firebird firebird-3.0

Firebird Db将图表帐户记录存储在表中:

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
  )

我必须编写查询,该查询仅从表中选择,例如最后一个节点,例如没有子节点的节点(child2,child3,subchild1,subchild2,subchild3和subchild4)。

enter image description here

2 个答案:

答案 0 :(得分:3)

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 Interbase 5.5中的^ 2)。当然,自那时以来,Firebird 3取得了长足的进步,但是仍然不建议使用这种“直接”方法。

更多的SQL传统方式和FB友好方式来表达它,尽管不那么直接且难以阅读,但仍将是Select t1.x from t1 LEFT JOIN t2 on t1.a=t2.b WHERE t2.y IS NULL

答案 1 :(得分:1)

您的查询需要执行以下操作:

select * from CHARTACC where ACCNTNUM not in (select ACCPARNT from CHARTACC)

要确切地说,请从该表中选择在其父字段中的任何位置都找不到同一表的标识符的项目。