【问题标题】:delete hierarchy rows in sql or javascript loops删除 sql 或 javascript 循环中的层次结构行
【发布时间】:2015-09-20 02:26:19
【问题描述】:

我正在使用 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);
      }
    });
  });
};

【问题讨论】:

    标签: javascript sql node.js postgresql loops


    【解决方案1】:

    Sql 解决方案。

    此递归查询为所有 TagIds 选择一组子 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      相关资源
      最近更新 更多