我正在使用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/