一张表table
字段为:id,parentid,name,用它可递归生成一棵树。
但是我现在想得到某一节点下的全部叶子,这个select语句怎么写?
假设我知道id='aaa'这个节点,我想得到以这个节点为根节点的全部叶子,注:
我只知道得到一棵树的全部叶子是这样写的:
select * from table where id not in (select parentid from table)
另外,所谓叶子就是最终节点,也就是没有儿子的节点。
我用的是access数据库。
字段为:id,parentid,name,用它可递归生成一棵树。
但是我现在想得到某一节点下的全部叶子,这个select语句怎么写?
假设我知道id='aaa'这个节点,我想得到以这个节点为根节点的全部叶子,注:
我只知道得到一棵树的全部叶子是这样写的:
select * from table where id not in (select parentid from table)
另外,所谓叶子就是最终节点,也就是没有儿子的节点。
我用的是access数据库。
你的表属于哪种情况。把什么都用SQL语句来实现,也并不是解决问题的好方法!
有两个条件:
1. 这些 id 的 parentid 是 'aaa'
2. 这些 id 不作为 parentidSELECT *
FROM table
WHERE (parentid='aaa') and
(id not in (SELECT parentid
FROM table))
提供另一种方法:此方法节点的级数必先定好。
就是更改数据表的结构。用户的资产类别是这样做的。
表结构如下
name,id,parentid,parentid1,parentid2,parentid3
..............................................
这样的话每条记录都有id,父亲的id,祖父的id...
要实现你讲的功能也就容易了。
除非子节点是你节点的值加某一个部分内容。
如:父节点:10
子节点:1001
孙节点:100101
。。
建议:
如果你现在的设计,建议一级一级的填啊。
先填完第一级,再填第一级的所有子节点的节点。
或者是展开时动态检测。
var
Node_Root,node_parent : TTreeNode;
str_sql1 : string;
str_parent1 : string;
begin
treeview1.Items.Clear;
Node_Root := treeview1.Items.AddChild(nil,'**'+datamodule1.CompanyName);
node_parent := Node_Root;
str_sql1:='select deptid +'+ '''--''' + '+ deptname as fieldcurrent,deptinid as fieldparent ' +
' from department ' +
' where accountid =''' + datamodule1.ZhangTao +'''';
str_parent1:=' parentid = ''*''';
Addtreenode(DataModule1.ADOConnection1,treeview1,node_parent,str_sql1,str_parent1);
Treeview1.Select(Node_Root);
TreeView1Click(self);
end;procedure Addtreenode(ADOConnection1 : TADOConnection ;treeview1 : TTreeview ; node_parent : TTreeNode ; str_sql : string ; str_parent : string);
{
str_sql format :
select deptid + '--' + deptname as fieldcurrent,deptinid as fieldparent
from department
[where accountid='0001']
只能有两个字段,前一字段为本级字段,后一字段为父级字段
str_parent format :
若str_sql含有"UNION"字符串则:
要用 where parentinid = 'parent_id' (where 父级字段 =<字符串>) 或者 and parentinid = 'parent_id' (and 父级字段 =<字符串>)
否则用: parentinid = 'parent_id'(父级字段 =<字符串>)
}
var
i : integer;
str_parenttmp : string;
str_sqlparamtmp: string;
node_tmp : TTreeNode;
ADOdatasettmp : TADODataSet;
begin
if (pos('WHERE',uppercase(str_sql)) = 0) and (pos('UNION',uppercase(str_sql)) = 0) then
str_sqlparamtmp := str_sql + ' where ' + str_parent
else
if (pos('WHERE',uppercase(str_sql)) <> 0) and (pos('UNION',uppercase(str_sql)) = 0) then
str_sqlparamtmp := str_sql + ' and ' + str_parent
else
str_sqlparamtmp := str_sql + str_parent; try
ADOdatasettmp := TADODataSet.Create(nil);
ADOdatasettmp.Connection := ADOConnection1;
with ADODataSettmp do
begin
//CommandText :='select deptid,deptname,deptinid from department where accountid=''' + datamodule1.zhangtao + ''' and parentid='''+ str_parent +'''';
CommandText := str_sqlparamtmp;
Open;
if RecordCount = 0 then
begin
Close;
Free;
exit;
end; First;
for i := 1 to RecordCount do
begin
str_parenttmp := copy(str_parent,1,pos('=',str_parent)) + '''' + string(Fields[1].Value) + '''';
node_tmp := treeview1.Items.AddChild(node_parent, string(ADOdatasettmp.Fields[0].Value));
Addtreenode(ADOConnection1,treeview1,node_tmp,str_sql,str_parenttmp);
Next;
end;
Close;
Free;
end; //with
ADOdatasettmp:=nil;
except
ADOdatasettmp.Close;
ADOdatasettmp.Free;
ADOdatasettmp:=nil;
showmessage(str_sqlparamtmp);
end;
end;
但是我现在想得到某一节点下的全部叶子,这个select语句怎么写?
假设我知道id='aaa'这个节点,我想得到以这个节点为根节点的全部叶子,注:
我只知道得到一棵树的全部叶子是这样写的:
select * from table where id not in (select parentid from table)
另外,所谓叶子就是最终节点,也就是没有儿子的节点。
我用的是access数据库。
---------------------------------------------------------------------
用parentid 保存当前节点的父亲节点,想得到以这个节点为根节点的全部儿子节点:
select * from table where parentid='aaa'
create table table1(id char(3),parentid char(3),name char(10))
insert into table1 values('1','0','化工原料')
insert into table1 values('2','1','氨类')
insert into table1 values('3','1','脂类')
insert into table1 values('4','2','乙氨酸')create procedure showtree
@id char(3),--要展开的节点
@no int --层次,传入为1,以后递增。这是存储过程的关键,就是逐层查找子节点
as
begin
if @no=1
select @no as cno,table1.* into #temp from table1 where parentid=@id
--如果@no为1,则表示搜索第一层数据,并建立临时表,加入结果数据
declare @tid char(3)
declare temp_sear cursor for select id from #temp where cno=@no
open temp_sear
fetch next from temp_sear into @tid
while @@FETCH_STATUS=0
begin
set @no=@no+1
insert into #temp select @no as cno,table1.* from table1 where parentid=@tid
fetch next from temp_sear into @tid
end
close temp_sear
DEALLOCATE temp_sear
if @no<32 --最深为32层
if (select count(*) from #temp where cno=@no)>0
exec showtree '',@NO --此处进行递归
end
select id,parentid,name from #temp order by id
go