我有一张表显示亲子关系.这种关系可以深入到n级.

我使用以下查询创建了一个示例表:

CREATE SEQUENCE relations_rel_id_seq
    INCREMENT BY 1
    NO MAXVALUE
    NO MINVALUE
    CACHE 1;
CREATE TABLE relations(
    rel_id bigint DEFAULT nextval('relations_rel_id_seq'::regclass) NOT NULL PRIMARY KEY,
    rel_name text,
    rel_display text,
    rel_parent bigint
);

SQLFiddle

我需要查询表并分层显示父子关系.关于如何使用SQL查询查询n级深度,我仍然不太了解.

对于sqlfiddle例如,预期的输出层次 struct :

rel1
    rel11
        rel111
        rel112
            rel1121
rel2
    rel21
        rel211
        rel212

N.B: n-level中的n值未知.

DB Design:

有没有更好的方式来表达这种关系呢? 数据库,便于查询.

推荐答案

对于Postgres,您可以使用递归公用表表达式:

with recursive rel_tree as (
   select rel_id, rel_name, rel_parent, 1 as level, array[rel_id] as path_info
   from relations 
   where rel_parent is null
   union all
   select c.rel_id, rpad(' ', p.level * 2) || c.rel_name, c.rel_parent, p.level + 1, p.path_info||c.rel_id
   from relations c
     join rel_tree p on c.rel_parent = p.rel_id
)
select rel_id, rel_name
from rel_tree
order by path_info;

基于您的示例的SQLFdle:http://sqlfiddle.com/#!11/59319/19

(我用下划线替换了用于缩进的空格,因为SQLF不能正确显示空格)

Database相关问答推荐

无法连接MatrixOne(来自GitHub)

如何在保持相同 Flyway 校验和的同时更正语法?

无法向 SiriDB 添加新副本

我应该使用哪种数据库模型在运行时动态修改实体/属性?

如何在 SQL Server 中将索引从一个表复制到另一个表

用于为 Android 设计 SQLite 数据库的开发人员工具

tzname字段/时区标识符名称的最大长度

MySQL JDBC Driver中cachePrepStmts和useServerPrepStmts有什么区别

FOR UPDATE和JOIN的 SQL 语义

我可以在没有数据源的情况下配置 Grails 吗?

在 SQL 数据库之间共享数据

是否有任何数据库支持自动索引创建?

如何在 PDO 中获取数据库名称?

如何在一行中显示 redis 中的所有键?

A QuerySet 按聚合字段值

cURL 和 PHP 显示1

Twisted + SQLAlchemy 和最好的方法

数据库查询时间复杂度

多币种 - 存储什么以及何时转换?

为什么在数据库设计中使用一对一的关系?