2010-07-26 6 views
85

Я пытаюсь удалить из нескольких таблиц сразу. Я сделал несколько исследований, и придумал этотКак удалить из нескольких таблиц в MySQL?

DELETE FROM `pets` p, 
      `pets_activities` pa 
     WHERE p.`order` > :order 
     AND p.`pet_id` = :pet_id 
     AND pa.`id` = p.`pet_id` 

Однако, я получаю эту ошибку

Uncaught Database_Exception [1064]: У вас ошибка в вашем SQL синтаксиса; проверьте руководство, которое соответствует версии сервера MySQL для правильного синтаксиса использовать вблизи «р, pets_activities ра ...

Я никогда не делал кросс таблицы удалить, прежде чем, так что я неопытный и застрял Теперь!

Что я делаю неправильно?

ответ

153

Использование JOIN в заявлении DELETE.

DELETE p, pa 
     FROM pets p 
     JOIN pets_activities pa ON pa.id = p.pet_id 
    WHERE p.order > :order 
     AND p.pet_id = :pet_id 

В качестве альтернативы вы можете использовать ...

DELETE pa 
     FROM pets_activities pa 
     JOIN pets p ON pa.id = p.pet_id 
WHERE p.order > :order 
    AND p.pet_id = :pet_id 

... удалить только из pets_activities

См http://dev.mysql.com/doc/refman/5.0/en/delete.html

Для одной таблицы удаляются, но с ссылочной целостности, есть другие способы делать с EXISTS, НЕ СУЩЕСТВУЕТ, IN, НЕ В И, и т. д. Но выше, где вы указываете, из каких таблиц удалить с помощью псевдоним, прежде чем предложение FROM может легко избавить вас от нескольких довольно узких мест. Я имею тенденцию обращаться к EXISTS в 99% случаев, а затем есть 1%, где синтаксис MySQL занимает день.

+5

Я попробовал это «удалить все в 1 запрос», присоединив 6 больших таблиц (каждый около ~ 15 тыс. Строк), и запрос занял 155 секунд, чтобы удалить 63 строки в 6 таблицах: O – techouse

+1

@cadman Это реальный правильный ответ; могут быть аргументы против его использования, но это очень полезно иногда –

+1

+1 Я согласен, что это в реальном правильном ответе, так как вопрос был не «должен ли ты», а «как». Однако мне было бы интересно услышать о 1%, потому что я не могу придумать ни одной ситуации, когда это было бы предпочтительнее. –

1

Синтаксис выглядит прямо ко мне ... попытаться изменить его, чтобы использовать INNER JOIN ...

Посмотрите на это: http://www.electrictoolbox.com/article/mysql/cross-table-delete/

+4

Слишком плохо, что вы не указали фактическое решение, потому что ссылка верна! – mycroes

17

Поскольку это, кажется, простой родитель отношения/ребенок между pets и pets_activities, вам было бы лучше создать ограничение внешнего ключа с помощью удаления каскада.

Таким образом, когда строка pets удаляется, связанные с ней строки pets_activities также автоматически удаляются.

Тогда ваш запрос становится простым:

delete from `pets` 
    where `order` > :order 
     and `pet_id` = :pet_id 
+0

Удаление каскадов вызывает ужасные аварии. –

+0

Спасибо Paxdiablo, я не уверен, как это сделать в MySQL, но я это рассмотрю. – alex

+2

@Erick, при условии, что вы настроили ссылочную целостность, каскадные удаления могут вызвать больше проблем, чем удаление самостоятельно. Мы уже знаем, что 'pa' является правильным дочерним элементом' p' из-за отображения 'id/pet_id'. – paxdiablo

2

У меня нет базы данных MySQL, чтобы проверить на в данный момент, но вы пробовали указать, что удалить до ЕКА? Например:

DELETE p, pa FROM `pets` p, 
     `pets_activities` pa 
    WHERE p.`order` > :order 
    AND p.`pet_id` = :pet_id 
    AND pa.`id` = p.`pet_id` 

Я думаю, что используемый вами синтаксис ограничен более поздними версиями mysql.

+1

Этот запрос выполнен успешно, однако он не удалял никаких строк (но я считаю, что он должен иметь). – alex

12

Используйте этот

DELETE FROM `articles`, `comments` 
USING `articles`,`comments` 
WHERE `comments`.`article_id` = `articles`.`id` AND `articles`.`id` = 4 

или

DELETE `articles`, `comments` 
FROM `articles`, `comments` 
WHERE `comments`.`article_id` = `articles`.`id` AND `articles`.`id` = 4 
+0

Nice - кажется лучше и проще, чем использование JOIN. Это лучшее решение, которое я вижу здесь .. спасибо! – gnB

+1

Нашли хорошую ссылку для использования этого и нескольких других вариантов на http://www.mysqltutorial.org/mysql-delete-statement.aspx –

0

Для тех, кто читает это в 2017 году, это, как я сделал что-то подобное.

DELETE pets, pets_activities FROM pets inner join pets_activities 
on pets_activities.id = pets.id WHERE pets.`order` > :order AND 
pets.`pet_id` = :pet_id 

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

DELETE table1, table2 FROM table1 inner join table2 on table2.id = table1.id 
WHERE [conditions] 

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

  • Нет связанных вопросов^_^