Две таблицы — как удалить строки, если идентификатор не указан в обеих таблицах

#mysql #sql #sql-delete

#mysql #sql #sql-удалить

Вопрос:

У меня есть две таблицы:

 listings(item_id, ...)
images(item_id,  ...)
  

Значение item_id одинаково в обеих таблицах — но я ошибся и удалил списки из таблицы «списки», не удалив также соответствующую строку в таблице «изображения».

Итак, я хочу удалить все строки во второй таблице «изображения», если item_id в ИЗОБРАЖЕНИЯХ не соответствует ни одному из более актуальных значений item_id в моей основной таблице «списки».

Как удалить все записи в таблице «изображения», на которые нет ссылок в «списках»?

Я экспериментировал со скриптом SQL и вложенным запросом, подобным этому:

 DELETE FROM images WHERE item_id IN
(SELECT item_id FROM images EXCEPT SELECT item_id FROM listings)
  

Но прежде чем я все испорчу, хотите подтвердить, правильно ли это?

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

1. В MySQL нет инструкции EXCEPT

Ответ №1:

Вы должны использовать вложенный запрос

 DELETE FROM images WHERE item_id NOT IN(SELECT item_id FROM listings)
  

Больше примеров и пояснений.

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

1. спасибо — это отлично сработало. Я только сейчас узнаю о подзапросах!

Ответ №2:

Вот хороший прием для решения этих деликатных ситуаций:

Перед выполнением запроса, который может нанести значительный ущерб, если написан неправильно, замените УДАЛЕНИЕ / ОБНОВЛЕНИЕ на ВЫБОР, чтобы увидеть, на какие строки повлияет ваш запрос. В вашем случае это было бы:

 SELECT * 
-- DELETE
FROM images WHERE item_id NOT IN (SELECT item_id FROM listings) 
  

Конечно, вы также хотите обезопасить себя, создав резервную копию базы данных перед выдачей такой команды. Даже если ваш запрос выглядит корректно с помощью теста SELECT, вы никогда не знаете наверняка…

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

1. Голосую за эту только потому, что мне действительно нравится идея выбора первой, и это то, что я всегда делаю, чтобы убедиться, что я избавляюсь от нужного материала. В противном случае, моя и Дастина понятнее.

2. Договорились о ясности запроса. Я поддержал вас, ребята, и обновил свой ответ, чтобы удовлетворить. Я просто хотел опубликовать трюк с выбором защитных запросов…

3. Защитные запросы, настоящая экономия времени!

Ответ №3:

Это сработало бы, или IN предложение также.

 DELETE
FROM image
WHERE item_id NOT IN (SELECT item_id FROM listings)
  

Ответ №4:

Для меня было бы понятнее сказать

 DELETE FROM images WHERE item_id NOT IN 
    (SELECT item_id FROM listings)