【发布时间】:2016-09-11 18:14:11
【问题描述】:
我有表 comment,我想通过输入 id 删除并删除所有子项,
以下两个查询均不删除所有层次结构数据,只删除自身和一个子行...
在with闭包中选择递归有什么问题吗?
评论
id | parent_comment_id
1 |
2 | 1
3 | 2
4 |
查询 1
WITH RECURSIVE coH AS (
SELECT co.id,
co.id AS rootId
FROM comment co
UNION ALL
SELECT coChild.id,
coChild.parent_comment_id as parentCommentId
FROM comment coChild
JOIN coH coP ON coP.id = coChild.parent_comment_id
)
DELETE FROM comment WHERE id IN (
SELECT id FROM coH WHERE rootId = $1
)
查询 2
DELETE FROM comment WHERE id IN (
WITH RECURSIVE coH AS (
SELECT co.id,
co.id AS rootId
FROM comment co
UNION ALL
SELECT coChild.id,
coChild.parent_comment_id as parentCommentId
FROM comment coChild
JOIN coH coP ON coP.id = coChild.parent_comment_id
)
SELECT id FROM coH WHERE rootId = $1
)
更新
var dbQuery = `DELETE FROM comment WHERE id IN (
WITH RECURSIVE coH (id, parentCommentId, rootId) AS (
SELECT co.id,
co.parent_comment_id as parentCommentId,
co.id AS rootId
FROM comment co
UNION ALL
SELECT coChild.id,
coChild.parent_comment_id as parentCommentId,
coP.rootId
FROM comment coChild
JOIN coH coP ON coP.id = coChild.parent_comment_id
)
SELECT id FROM coH WHERE rootId = $1
)`;
【问题讨论】:
-
您的查询似乎是正确的,但以错误的顺序删除可能会导致外键违规。您可以通过没有外键(不推荐!)或使用 ON DELETE CASCADE 或 DEFERRABLE 的外键来解决此问题。
-
@ZiggyCrueltyfreeZeitgeister 我找到了这个答案stackoverflow.com/a/10381384/5593189我在我的问题中更新,它可以删除所有,但我不知道为什么?
coH (id, parentCommentId, rootId)支撑是什么?并在第一部分选择为什么需要co.parent_comment_id as parentCommentId? -
@ZiggyCrueltyfreeZeitgeister 我没有在评论表中设置外键。我可以设置
comment.parent_comment_idfkcomment.id吗?如果该列可以为空仍然可以设置外键?
标签: sql postgresql recursion hierarchy postgresql-9.4