firebird数据库中存储着“帐户”表:
Acc_id-唯一,整数,不为null,主键,
Acc_num-唯一,varchar(30)
Prnt_id-整数
Acc_Title-说明,文本说明
Acc_id Acc_num Prnt_id Acc_Title
0 Base Null Base account
1 1000 0 Current assets account
2 1100 1 some text
3 1110 2 some text
4 1110 1 3 some text
5 1110 1 15 4 some text
6 2000 0 some text
7 2700 6 some text
8 1110 1 16 4 some text
...
101 1155 1 1155 some text
102 1125 1100 some text
例如,我必须在db中插入帐户2700的记录。在编辑控件中,我输入帐号2700,并且必须确定其父级为帐户2000(parent_id = 6)。 如何使用firebird-sql找出帐户2000是帐户2700的父级或1120是1125等的父级?
如果我错误继续使用1000或1100或1110帐户并要创建帐户1125,则 sql查询必须猜测父帐户是帐户1100,并且必须将其添加为1100帐户的子帐户< / strong>,而不是1000或1110。
答案 0 :(得分:0)
接下来您再不告诉您有关您的问题的信息。您必须将表格中的样本数据显示为简短的摘要!因此,我们只能尝试猜测您的意思,如果我们猜错了,那就倒霉了。
VARCHAR
列Title
中-而不是存储在Acc_number
中,UNIQUE CONSTRAINT
字段上使用UNIQUE INDEX
或Title
来丰富SQL表,则标题可能不是唯一的,index
(否则会很慢),并且acc_id
字段和parent_id
字段上都有一个
您的查询如下所示:
Select t1.*
from MyTable t1, MyTable t2
where t2.parent_id = t1.acc_id
and t2.title = :TitleParameter
根据所使用的Delphi DB访问库(还有很多https://github.com/petdance/bobby-tables/issues/98),代码将如下所示:
Var qGetParent: TSqlQuery;
.....
begin
if nil = qGetParent then begin
qGetParent := TSqlQuery.Create( MySQLConnection );
qGetParent.SQL.Text := 'select...'; // see above
qGetParent.Prepared := true; // make SQL server compile this query only once
end;
qGetParent.Params[0].AsString := '1200';
// we only have one parameter, so somewhat slow .ParamByName can easily be skipped
qGetParent.Open;
while not qGetParent.EOF do begin
// listing 0 or 1 or many rows returned by the query
qGetParent.Next;
end;
qGetParent.Close;
end;
当然,很难理解为什么您需要这样的查询。您在哪里采用“ 1200”格式?从一个程序。但是该程序(如屏幕快照中的树一样)已经知道为标题为acc_id
的行设置了哪个1200
值!您已经在程序中包含有关树的数据。
答案 1 :(得分:0)
因此,您需要猜测哪个节点最适合作为父节点?好吧:
with recursive a (n) as (
select cast(:N as varchar(30)) from rdb$database
union all
select
case
when n containing ' ' then left(n,char_length(n)-position(' ',reverse(n)))
when char_length(n)=1 then 'Base'
else left(n,char_length(n)-1)
end
from a
where char_length(n)>=1 and n<>'Base')
select ac.acc_id,ac.acc_number
from a
join accounts ac on ac.acc_number=rpad(a.n,4,'0')
fetch first 1 row only