javascript - 删除 sql 或 javascript 循环中的层次结构行

标签 javascript sql node.js postgresql loops

我正在使用postgresql,我想找到一种方法来递归删除行和属于它的子行。 sql 或 javascript 循环
例如
如果我想删除 TagId: 0 ,还需要删除 TagId: 0, 2, 3, 4, 5 ,查找是否有 TagId在其他行中 ParentTagId 然后递归查找其他行....

我只在下面写了一部分代码,我不知道如何循环保留选择和删除..

"TagId" serial NOT NULL,
"Name" character varying,
"ParentTagId" integer,
CONSTRAINT "Tag_pkey" PRIMARY KEY ("TagId")

TagId | Name | ParentTagId
0     |      |    
1     |      |
2     |      |0
3     |      |2
4     |      |3
5     |      |0

-

var id = 0;

function deleteHierarchy(id) {
   // if rowCount > 0 then select and delete
}

var selectTagResult = yield selectTag(id);
var deleteTagResult = yield deleteTag(id);

if (selectTagResult.result.rowCount > 0) {
  var rows = selectTagResult.result.rows;
  for (var i = 0; i < rows.length; i++) {
    var id = rows[i].TagId;
    var selectTagResult = yield selectTag(id);
    var deleteTagResult = yield deleteTag(id);
    // ..
  }
}

-

var selectTag = function(parentTagId) {
  return new Promise(function (fulfill, reject){
    var query = 'SELECT * FROM "Tag" WHERE "ParentTagId" = $1 ORDER BY "Sequence" ASC';
    dbClient.query(query,[parentTagId], function(error, result) {
      var o = {};
      if (error != null) {
        o.error = error;
        fulfill(o);
      } else {
        o.result = result;
        fulfill(o);
      }
    });
  });
};

var deleteTag = function(id) {
  return new Promise(function (fulfill, reject){
    var query = 'DELETE FROM "Tag" WHERE "TagId" = $1';
    dbClient.query(query,[id], function(error, result) {
      var o = {};
      if (error != null) {
        o.error = error;
        fulfill(o);
      } else {
        o.result = result;
        fulfill(o);
      }
    });
  });
};

最佳答案

Sql 解决方案。

此递归查询为所有 TagId 选择一组子 ID(作为 Children):

with recursive "Tags"("TagId", "ChildId", "Children") as (
    select "TagId", "TagId", array["TagId"]
    from "Tag"
union
    select "Tags"."TagId", "Tag"."TagId", "Tags"."Children"|| "Tag"."TagId"
    from "Tags"
    join "Tag" on "Tags"."ChildId" = "Tag"."ParentTagId"
    ),
"Children" as (
    select "TagId", unnest("Children")
    from "Tags"
    )
select "TagId", array_agg(distinct unnest) "Children"
from "Children"
group by 1
order by 1;

 TagId |  Children
-------+-------------
     0 | {0,2,3,4,5}
     1 | {1}
     2 | {2,3,4}
     3 | {3,4}
     4 | {4}
     5 | {5}
(6 rows)

因此,这个选择 TagId = 0 的子级:

with recursive "Tags"("TagId", "ChildId", "Children") as (
    select "TagId", "TagId", array["TagId"]
    from "Tag"
union
    select "Tags"."TagId", "Tag"."TagId", "Tags"."Children"|| "Tag"."TagId"
    from "Tags"
    join "Tag" on "Tags"."ChildId" = "Tag"."ParentTagId"
    ),
"Children" as (
    select "TagId", unnest("Children")
    from "Tags"
    )
select array_agg(distinct unnest) "Children"
from "Children"
where "TagId" = 0

  Children
-------------
 {0,2,3,4,5}
(1 row) 

最后,此查询删除 TagId = 0 及其所有子项:

with recursive "Tags"("TagId", "ChildId", "Children") as (
    select "TagId", "TagId", array["TagId"]
    from "Tag"
union
    select "Tags"."TagId", "Tag"."TagId", "Tags"."Children"|| "Tag"."TagId"
    from "Tags"
    join "Tag" on "Tags"."ChildId" = "Tag"."ParentTagId"
    ),
"Children" as (
    select "TagId", unnest("Children")
    from "Tags"
    )
delete from "Tag"
where "TagId" in (
    select distinct unnest
    from "Children"
    where "TagId" = 0
    )
returning *;

 TagId | Name | ParentTagId
-------+------+-------------
     2 |      |           0
     0 |      |
     4 |      |           3
     3 |      |           2
     5 |      |           0
(5 rows)


DELETE 5

关于javascript - 删除 sql 或 javascript 循环中的层次结构行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32671021/

相关文章:

node.js - Socket.io + SSL + 自签名 CA 证书在连接时出错

node.js - 从sql文件生成sequelize模型

javascript - 如何从另一个 .js 文件添加 Express 路由端点?

javascript - 用 JS 显示一个随机的 css Sprite

JavaScript 对象克隆

MYSQL返回其他数据库表中不存在的行ID列表

sql - 在 SQL 中创建不同长度的序列

mysql - 使用 MySQL,我如何知道谁每年至少参加一次事件?

javascript - 淡入淡出图像javascript

javascript - 在 javascript 中验证表单的更好方法