2016-05-16 2 views
1

У меня есть таблица comment, и я хочу, чтобы удалить путем ввода id, а также удалить все дочерние,удалить/выбрать иерархии данных в PostgreSQL

ниже двух запросов и не удалять всю иерархию данных, удалить только сам и один ребенок строк ...

есть ли что-то неправильное, если выбрать рекурсивный в 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 
) 

UPDATE

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 
)`; 
+0

Ваши запросы, кажется правильным, но удаление в неправильном порядке может привести к внешним ключам нарушений. Вы можете решить эту проблему, не имея внешнего ключа (не рекомендуется!) Или с помощью вашего внешнего ключа с ON DELETE CASCADE или с его DEFERRABLE. –

+0

@ZiggyCrueltyfreeZeitgeister Я нашел этот ответ http://stackoverflow.com/a/10381384/5593189 Я обновляю в своем вопросе, он работает, чтобы удалить все, но я не знаю почему? что такое 'coH (id, parentCommentId, rootId)' brace for? и в первой части выберите в с почему нужно сделать 'co.parent_comment_id как parentCommentId'? – user1575921

+0

@ZiggyCrueltyfreeZeitgeister Я не задавал внешний ключ в таблице комментариев. могу ли я установить 'comment.parent_comment_id' fk' comment.id'? если столбец может иметь значение null, он может установить внешний ключ? – user1575921

ответ

1

Держите его просто поместите параметр в исходном запросе рекурсивных с:

with recursive cbase as (
    select 1 as id -- select $1 as id 

    union all 

    select child.id 
    from comment as child 
    join cbase on cbase.id = child.parent_comment_id 
) 
delete from comment 
where id in (select * from cbase) 
returning id; 

id 
---- 
    1 
    2 
    3 
(3 rows) 

DELETE 3  
+0

спасибо за ответ и пример кода! 'select 1 as id' или' select $ 1 as id'? Я все еще хочу знать, почему мой запрос не работает, что отличает мой первоначальный запрос и запрос на обновление, заставляют его работать? – user1575921

+1

Ваш запрос не работает, потому что он исключает некоторые строки в предложении where. При этом условии вы всегда получите не более двух строк. 'select 1 ...' является только примером для проверки запроса, вы должны использовать 'select $ 1 ...' конечно. – klin

+0

Я получаю ошибку 'operator не существует: text = integer' ...' JOIN co ON co.id = child.parent_comment_id' ?? – user1575921

Смежные вопросы