sql - 递归选择行

标签 sql postgresql recursive-query

我正在使用 postgresql,我试图了解如何选择递归。
我制作了一个如下所示的示例表,如果 tagId 为 5 如何递归选择直到 ParentTagId 为 null(获取 1、3、5 行)?
如果 tagId = 1 如何向下递归选择(获取 1、3、4、5 行)?

CREATE TABLE IF NOT EXISTS "Tag"(
"TagId" SERIAL NOT NULL,
"ParentTagId" integer,
"Name" varchar,
PRIMARY KEY ("TagId")
);

TagId | ParentTagId | Name |
1     |             | 1a   |
2     |             | 1b   |
3     | 1           | 2a   |
4     | 1           | 2b   |
5     | 3           | 3a   |


var tagId = 5;

var selectTagRecursiveUp = function(tagId) {
  var query = 'SELECT * FROM "Tag" WHERE "TagId" = $1';
  dbClient.query(query, [tagId], function(error, result) {    
  });
});

最佳答案

这可以通过 recursive common table expression 来完成:

with recursive tag_tree as (
   select "TagId", "ParentTagId", "Name"
   from "Tag"
   where "TagId" = 5
   union all
   select parent."TagId", parent."ParentTagId", parent."Name"
   from "Tag" parent
     join tag_tree child on parent."TagId" = child."ParentTagId"
)
select *
from tag_tree;

要在另一个方向上遍历树,您只需使用不同的“ anchor ”查询并在递归部分交换连接条件:

with recursive tag_tree as (
   select "TagId", "ParentTagId", "Name"
   from "Tag"
   where "TagId" = 1
   union all
   select child."TagId", child."ParentTagId", child."Name"
   from "Tag" child
     join tag_tree parent on parent."TagId" = child."ParentTagId"
)
select *
from tag_tree;

SQLFiddle 示例:http://sqlfiddle.com/#!15/5ed10/1


请注意,使用带引号的标识符通常不是一个好主意。他们比他们值得的麻烦多得多

关于sql - 递归选择行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33422640/

相关文章:

sql - CHOOSE() 未按预期工作

mysql - 使 MySQL IN 子句区分大小写

ruby-on-rails - Windows 和 SQLite3 到 Ubuntu 和 PostgreSQL 的迁移问题

sql - Postgres : Using WITH RECURSIVE to build list of item and their parents

SQL 查询以获取主管层次结构的列表。员工 --> 主管 --> 主管

SQL分组interescting/overlapping行

php - 我似乎无法让这个 sql 查询按照我想要的方式工作

mysql - MySql 连接的限制

Django - 合并两个相同应用程序的最佳方式

sql - 使用两个表仅列出最大日期