Удалить с 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 [...]

Взносы от Carpetsmoker и др.

Вы также можете использовать 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 было бы WHEREEXISTS

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
Другие вопросы по тегам