Удалить с Join в MySQL
Вот скрипт для создания моих таблиц:
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 ответов
Вам просто нужно указать, что вы хотите удалить записи из posts
Таблица:
DELETE posts
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id
РЕДАКТИРОВАТЬ: Для получения дополнительной информации вы можете увидеть этот альтернативный ответ
Поскольку вы выбираете несколько таблиц, таблица для удаления больше не является однозначной. Вам необходимо выбрать:
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 [...]
Вы также можете использовать ALIAS, как это работает, просто использовать его в моей базе данных! т это таблица должна быть удалена из!
DELETE t FROM posts t
INNER JOIN projects p ON t.project_id = p.project_id
AND t.client_id = p.client_id
Или то же самое, с немного другим (более дружелюбным) синтаксисом:
DELETE FROM posts
USING posts, projects
WHERE projects.project_id = posts.project_id AND projects.client_id = :client_id;
Кстати, с MySQL использование соединений почти всегда намного быстрее, чем подзапросы...
Я более привык к решению подзапроса, но я не пробовал его в MySQL:
DELETE FROM posts
WHERE project_id IN (
SELECT project_id
FROM projects
WHERE client_id = :client_id
);
Удаление одной таблицы:
Для того, чтобы удалить записи из 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
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 необходимо удалить.
Попробуйте как ниже:
DELETE posts.*,projects.*
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id;
Еще один метод удаления с использованием дополнительного выбора, который лучше, чем с помощью 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
метод.
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);
Одно из решений - использовать подзапрос
DELETE FROM posts WHERE post_id in (SELECT post_id FROM posts p
INNER JOIN projects prj ON p.project_id = prj.project_id
INNER JOIN clients c on prj.client_id = c.client_id WHERE c.client_id = :client_id
);
Подзапрос возвращает идентификатор, который необходимо удалить; все три таблицы связаны с помощью объединений, и удаляются только те записи, которые соответствуют условию фильтра (в вашем случае, т.е. client_id в предложении where).
Если объединение не работает для вас, вы можете попробовать это решение. Он предназначен для удаления потерянных записей из t1, когда не используются внешние ключи + определенное условие где. Т.е. он удаляет записи из таблицы table1, которые имеют пустое поле "code" и которые не имеют записей в таблице table2, соответствующие полю "name".
delete table1 from table1 t1
where t1.code = ''
and 0=(select count(t2.name) from table2 t2 where t2.name=t1.name);
Попробуй это,
DELETE posts.*
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id
- Обратите внимание, что вы не можете использовать псевдоним над таблицей, где вам нужно удалить
DELETE tbl_pagos_activos_usuario
FROM tbl_pagos_activos_usuario, tbl_usuarios b, tbl_facturas c
Where tbl_pagos_activos_usuario.usuario=b.cedula
and tbl_pagos_activos_usuario.cod=c.cod
and tbl_pagos_activos_usuario.rif=c.identificador
and tbl_pagos_activos_usuario.usuario=c.pay_for
and tbl_pagos_activos_usuario.nconfppto=c.nconfppto
and NOT ISNULL(tbl_pagos_activos_usuario.nconfppto)
and c.estatus=50