SQL查询在一行中选择父级和子级名称

问题描述

我在hsqldb中有一个表,像这样的值

enter image description here

如何编写显示如下的查询

enter image description here

解决方法

您在这里:

with recursive
n (root_id,id,title,parent) as (
  select id as root_id,name,parent from t
 union
  select n.root_id,t.id,t.name || '/' || n.title,t.parent
  from n
  join t on t.id = n.parent
)
select title as name from n where parent is null order by root_id

结果:

NAME      
----------
A         
A/A1      
B         
B/B1      
C         
C/C1      
A/A1/A2   
A/A1/A3   
A/A1/A3/A4
B/B1/B3   

作为参考,这是我用来测试的数据脚本:

create table t (id int,name varchar(10),parent int);

insert into t (id,parent) values
  (0,'A',null),(1,'A1',0),(2,'B',(3,'B1',2),(4,'C',(5,'C1',4),(6,'A2',1),(7,'A3',(8,'A4',7),(9,'B3',3);
,

您可以使用递归查询:

with recursive cte (id,parent,path,lvl) as
    select id,0 from mytable
    union all
    select c.id,c.name,t.parent,concat(t.name,'/',c.path),c.lvl + 1
    from cte c
    inner join mytable t on t.id = c.parent_id
)
select *
from cte c
where lvl = (select max(c1.lvl) from cte c1 where c1.id = c.id)

查询选择整个表,然后爬到每一行的层次结构树。这种方法的好处是可以正确处理“断”树(例如,像一个有无效父母的孩子)。

,

基于接受的答案的另一种更简单的查询。我们仅从根(具有空父级的行)开始,每次执行联合时,仅添加几行。如答案所示,这种查询不会选择具有无效父ID的子行:

with recursive n (root_id,parent from t where parent is null
 union
  select n.root_id,n.title || '/' || t.name,t.parent
  from t
  join n on n.id = t.parent
)
select * from n

对于这种类型的表,必须添加设计中隐含的引用约束。当表变大时,这将加快查询速度,并避免损坏父ID。

alter table t add constraint pk primary key(id)
alter table t add constraint fk foreign key (parent) references t(id)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...