Удалить с Join в MySQL - PullRequest
       89

Удалить с Join в MySQL

456 голосов
/ 17 марта 2009

Вот скрипт для создания моих таблиц:

CREATE TABLE clients (
   client_i INT(11),
   PRIMARY KEY (client_id)
);
CREATE TABLE projects (
   project_id INT(11) UNSIGNED,
   client_id INT(11) UNSIGNED,
   PRIMARY KEY (project_id)
);
CREATE TABLE posts (
   post_id INT(11) UNSIGNED,
   project_id INT(11) UNSIGNED,
   PRIMARY KEY (post_id)
);

В моем PHP-коде при удалении клиента я хочу удалить все сообщения проектов:

DELETE 
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id;

Таблица сообщений не имеет внешнего ключа client_id, только project_id. Я хочу удалить сообщения в проектах, которые прошли client_id.

Сейчас это не работает, потому что ни одно сообщение не удалено.

Ответы [ 13 ]

1166 голосов
/ 16 ноября 2010

Вам просто нужно указать, что вы хотите удалить записи из таблицы posts:

DELETE posts
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id

РЕДАКТИРОВАТЬ: Для получения дополнительной информации вы можете увидеть этот альтернативный ответ

73 голосов
/ 23 марта 2015

Поскольку вы выбираете несколько таблиц, таблица для удаления больше не является однозначной. Вам нужно выбрать :

DELETE posts FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id

В этом случае table_name1 и table_name2 - это одна и та же таблица, поэтому это будет работать:

DELETE projects FROM posts INNER JOIN [...]

Вы даже можете удалить из обеих таблиц, если хотите:

DELETE posts, projects FROM posts INNER JOIN [...]

Обратите внимание, что order by и limit не работают при удалении из нескольких таблиц .

Также помните, что если вы объявляете псевдоним для таблицы, вы должны использовать псевдоним при обращении к таблице:

DELETE p FROM posts as p INNER JOIN [...]

Взносы от Carpetsmoker и т. Д. .

48 голосов
/ 01 сентября 2011

Или то же самое, с немного другим (более дружелюбным) синтаксисом:

DELETE FROM posts 
USING posts, projects 
WHERE projects.project_id = posts.project_id AND projects.client_id = :client_id;

Кстати, MySQL с использованием объединений почти всегда работает быстрее, чем подзапросы ...

39 голосов
/ 15 марта 2014

Вы также можете использовать ALIAS, как это работает, просто используйте его в моей базе данных! t таблица должна быть удалена из!

DELETE t FROM posts t
INNER JOIN projects p ON t.project_id = p.project_id
AND t.client_id = p.client_id
24 голосов
/ 17 марта 2009

Я более привык к решению подзапроса, но я не пробовал его в MySQL:

DELETE  FROM posts
WHERE   project_id IN (
            SELECT  project_id
            FROM    projects
            WHERE   client_id = :client_id
        );
11 голосов
/ 05 августа 2015

УДАЛИТЬ MySQL с помощью JOIN

Обычно вы используете INNER JOIN в операторе SELECT для выбора записей из таблицы, которые имеют соответствующие записи в других таблицах. Мы также можем использовать предложение INNER JOIN с оператором DELETE для удаления записей из таблицы, а также соответствующих записей в других таблицах, например, чтобы удалить записи из таблиц T1 и T2, которые удовлетворяют определенному условию, вы используете следующий оператор:

DELETE T1, T2
FROM T1
INNER JOIN T2 ON T1.key = T2.key
WHERE condition

Обратите внимание, что вы ставите имена таблиц T1 и T2 между DELETE и FROM. Если вы опустите таблицу T1, оператор DELETE удалит только записи в таблице T2, а если вы опустите таблицу T2, будут удалены только записи в таблице T1.

Условие соединения T1.key = T2.key указывает соответствующие записи в таблице T2, которые необходимо удалить.

Условие в предложении WHERE указывает, какие записи в T1 и T2 необходимо удалить.

9 голосов
/ 14 августа 2016

Удалить одну таблицу:

Чтобы удалить записи из таблицы posts:

DELETE ps 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

Чтобы удалить записи из таблицы projects:

DELETE pj 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

Чтобы удалить записи из таблицы clients:

DELETE C
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id;

Удалить несколько таблиц:

Чтобы удалить записи из нескольких таблиц из объединенных результатов, необходимо указать имена таблиц после DELETE в виде списка через запятую:

Предположим, вы хотите удалить записи из всех трех таблиц (posts, projects, clients) для конкретного клиента:

DELETE C,pj,ps 
FROM clients C 
INNER JOIN projects pj ON C.client_id = pj.client_id
INNER JOIN posts ps ON pj.project_id = ps.project_id
WHERE C.client_id = :client_id
7 голосов
/ 06 марта 2013

Попробуйте как ниже:

DELETE posts.*,projects.* 
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id;
4 голосов
/ 13 июня 2015
mysql> INSERT INTO tb1 VALUES(1,1),(2,2),(3,3),(6,60),(7,70),(8,80);

mysql> INSERT INTO tb2 VALUES(1,1),(2,2),(3,3),(4,40),(5,50),(9,90);

УДАЛЕНИЕ записей из одной таблицы:

mysql> DELETE tb1 FROM tb1,tb2 WHERE tb1.id= tb2.id;

УДАЛИТЬ ЗАПИСИ ИЗ обеих таблиц:

mysql> DELETE tb2,tb1 FROM tb2 JOIN tb1 USING(id);
4 голосов
/ 12 сентября 2012

Другой метод удаления с использованием дополнительного выбора, который лучше, чем использование IN, будет WHERE EXISTS

DELETE  FROM posts
WHERE   EXISTS ( SELECT  1 
                 FROM    projects
                 WHERE   projects.client_id = posts.client_id);

Одной из причин использования этого вместо объединения является то, что DELETE с JOIN запрещает использование LIMIT. Если вы хотите удалить блоки, чтобы не создавать полных блокировок таблицы, вы можете добавить LIMIT, используя этот метод DELETE WHERE EXISTS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...