nig*_*fly 0 sql postgresql common-table-expression
以下是我的表格格式.表名:: USERS
userid reporttouserid
------ ------------
101 NULL
102 101
103 102
Run Code Online (Sandbox Code Playgroud)
现在我需要一个查询来列出101下的所有子用户ID 102和103两者(103是间接在101以下,因为其父102在101以下)
我在postgresql中看到了常见的表表达式,但却无法弄清楚如何去做.
在PostgreSQL文档涵盖了这个主题.请参阅该页面上给出的递归CTE示例.
递归CTE可能有点难以掌握,但一旦使用它们就非常强大.阅读文档并进行一些实验; 你会明白的.
(请始终提及您的PostgreSQL版本,并在您的问题中以表格形式显示所需的输出).
给出演示数据:
create table users (
userid integer primary key,
reporttouserid integer references users(userid)
);
insert into users(userid, reporttouserid) values (101,null), (102,101), (103,102);
Run Code Online (Sandbox Code Playgroud)
(如果可能的话,请在问题中提供此信息,必须创建它是一件痛苦的事)
您可以使用以下内容递归地遍历图形:
WITH RECURSIVE flatusers(userid, reporttouserid, baseuserid) AS (
SELECT userid, reporttouserid, userid AS baseuserid
FROM users WHERE reporttouserid IS NULL
UNION ALL
SELECT u.userid, u.reporttouserid, f.baseuserid
FROM flatusers f
INNER JOIN users u ON f.userid = u.reporttouserid
)
SELECT * FROM flatusers;
Run Code Online (Sandbox Code Playgroud)
产生如下输出:
userid | reporttouserid | baseuserid
--------+----------------+------------
101 | | 101
102 | 101 | 101
103 | 102 | 101
(3 rows)
Run Code Online (Sandbox Code Playgroud)
我相信你可以从那里找出去哪里.在使用它之前,请确保您了解递归CTE.
请注意,PostgreSQL(至少9.4或更早版本)不能(不幸的是)将quals推向CTE术语,即使对于非递归CTE也是如此.如果您添加WHERE baseuserid = 101到查询中,查询仍将生成整个展平表,然后将大部分表扔掉.如果只想对一个 baseuserid 执行此递归操作,则必须在递归CTE术语的静态联合部分中添加适当的WHERE子句WHERE reporttouserid IS NULLterm.
| 归档时间: |
|
| 查看次数: |
804 次 |
| 最近记录: |