Удаление сирот при самосоединении

#mysql #sql #self-join

#mysql #sql #самосоединение

Вопрос:

Вариант использования довольно прост. После просмотра таблицы комментариев из нескольких миллионов строк. Мы понимаем, что есть много сиротских дочерних комментариев.

Следующий запрос не работает

 DELETE c.* FROM `comment` c 
where c.parentId not in (select id from `comment`)  
  

В нем говорится что-то вроде:

Статический анализ:

во время анализа были обнаружены 3 ошибки.

Неожиданный токен. (рядом с «c» в позиции 7) Неожиданный токен. (рядом с «.» в позиции 8) Неожиданный токен. (рядом с «*» в позиции 9)

MySQL сказал: Документация

1093 — Вы не можете указать целевую таблицу ‘c’ для обновления в предложении FROM

Я понимаю проблему, но не могу придумать альтернативу. Я очень плох в SQL

Комментарии:

1. Что бы вы ни делали, проверьте эти теории на предмет глобальных обновлений и удалений в фиктивных таблицах

Ответ №1:

Для этой операции вам нужно использовать left join :

 DELETE c
    FROM comment c  LEFT JOIN
         comment cp
         ON c.parentId = cp.id
    WHERE cp.id IS NULL and c.parentId is not null;
  

Обратите внимание: я думаю, вам следует быть осторожным. Действительно ли у всех комментариев есть родительский элемент, который является комментарием?

Комментарии:

1. Это кажется не совсем правильным. Я заменил DELETE на SELECT, и это дало слишком много (неправильных) записей

2. @PhamHuyAnh . . . Я подозреваю, что проблема в том, что c.parentId этого не должно быть NULL .