Usuń z Join w MySQL

Oto skrypt do tworzenia tabel:

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)
);

W moim kodzie PHP, usuwając klienta, chcę usunąć wszystkie posty projektów:

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

Tabela postów nie posiada klucza obcego client_id, tylko project_id. Chcę usunąć posty w projektach, które przeszły client_id.

To nie działa w tej chwili, ponieważ żadne posty nie są usuwane.

 525
Author: octano, 2009-03-17

14 answers

Musisz tylko określić, że chcesz usunąć wpisy z tabeli posts:

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

EDIT: aby uzyskać więcej informacji, możesz zobaczyć alternatywną ODPOWIEDŹ

 1315
Author: Yehosef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:58

Ponieważ wybierasz wiele tabel, tabela do usunięcia nie jest już jednoznaczna. Musisz wybrać :

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

W tym przypadku table_name1 i table_name2 są tą samą tabelą, więc to zadziała:

DELETE projects FROM posts INNER JOIN [...]

Możesz nawet usunąć z obu tabel, jeśli chcesz:

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

Zauważ, że order by i limit nie działa w przypadku usuwania wielu tabel .

Należy również pamiętać, że jeśli zadeklarujesz alias dla tabeli, musisz użyć tego aliasu w odniesieniu do tabela:

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

składki od Carpetsmoker i etc.

 91
Author: Pacerier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-16 07:47:30

Lub to samo, z nieco inną (IMO bardziej przyjazną) składnią:

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

BTW, z mysql używając joins jest prawie zawsze o wiele szybciej niż subqueries...

 51
Author: ivanhoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-01 04:14:09

Można również użyć ALIAS jak to działa po prostu użył go w mojej bazie danych! t jest tabela trzeba usunąć z!

DELETE t FROM posts t
INNER JOIN projects p ON t.project_id = p.project_id
AND t.client_id = p.client_id
 44
Author: Property Spain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-15 15:11:15

Jestem bardziej przyzwyczajony do rozwiązania subquery do tego, ale nie próbowałem go w MySQL:

DELETE  FROM posts
WHERE   project_id IN (
            SELECT  project_id
            FROM    projects
            WHERE   client_id = :client_id
        );
 25
Author: yukondude,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-17 01:52:46

Single Table Delete:

W celu usunięcia wpisów z tabeli 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;

W celu usunięcia wpisów z tabeli 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;

W celu usunięcia wpisów z tabeli 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;

Usuwanie Wielu Tabel:

Aby usunąć wpisy z wielu tabel z połączonych wyników, należy podać nazwy tabel po DELETE jako oddzielone przecinkami lista:

Załóżmy, że chcesz usunąć wpisy ze wszystkich trzech tabel (posts,projects,clients) dla konkretnego klienta:

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
 14
Author: 1000111,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-14 04:12:47

MySQL usuwanie rekordów za pomocą JOIN

W instrukcji SELECT zazwyczaj używa się INNER JOIN, aby wybrać rekordy z tabeli, które mają odpowiednie rekordy w innych tabelach. Możemy również użyć klauzuli INNER JOIN z instrukcją DELETE do usuwania rekordów z tabeli, a także odpowiednich rekordów z innych tabel, np. do usuwania rekordów z tabel T1 i T2, które spełniają określony warunek, używamy następującej instrukcji:

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

Zauważ, że umieszczasz nazwy tabel T1 i T2 pomiędzy DELETE a FROM. Jeśli pominie się tabelę T1, polecenie DELETE usunie tylko rekordy w tabeli T2, a jeśli pominie się tabelę T2, zostaną usunięte tylko rekordy w tabeli T1.

Warunek przyłączenia T1.klucz = T2.key określa odpowiednie rekordy w tabeli T2, które należy usunąć.

Warunek w klauzuli WHERE określa, które rekordy W T1 i T2 należy usunąć.

 11
Author: Aman Garg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-05 05:54:56

Spróbuj jak poniżej:

DELETE posts.*,projects.* 
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id;
 7
Author: Sangeetha Narayana Moorthy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-06 11:59:46

Inną metodą usuwania przy użyciu sub select, która jest lepsza niż przy użyciu IN, jest WHERE EXISTS

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

Jednym z powodów, aby użyć tego zamiast join jest to, że DELETE z JOIN zabrania używania LIMIT. Jeśli chcesz usunąć w blokach, aby nie tworzyć pełnych blokad tabeli, możesz dodać LIMIT Użyj tej metody DELETE WHERE EXISTS.

 4
Author: Jim Clouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-25 21:17:21
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);

Usuń rekordy z jednej tabeli:

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

Usuń rekordy z obu tabel:

mysql> DELETE tb2,tb1 FROM tb2 JOIN tb1 USING(id);
 4
Author: zloctb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-13 05:50:06

Jeśli join nie działa dla ciebie, możesz spróbować tego rozwiązania. Służy do usuwania rekordów osieroconych z t1, gdy nie używasz kluczy obcych + warunek szczególny where. Czyli usuwa rekordy z table1, które mają puste pole "code" i które nie mają rekordów w table2, pasujące przez pole "name".

delete table1 from table1 t1 
    where  t1.code = '' 
    and 0=(select count(t2.name) from table2 t2 where t2.name=t1.name);
 1
Author: Kristjan Adojaan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-07 08:55:04

Spróbuj tego,

DELETE posts.*
FROM posts
INNER JOIN projects ON projects.project_id = posts.project_id
WHERE projects.client_id = :client_id
 0
Author: Silambarasan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 09:18:58

Jednym z rozwiązań jest użycie subquery

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 
);

Zapytanie podrzędne zwraca ID, które należy usunąć; wszystkie trzy tabele są połączone za pomocą joins i usuwane są tylko te rekordy, które spełniają warunek filtra (w Twoim przypadku, tj. client_id w klauzuli where).

 0
Author: Adeel Raza Azeemi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-27 10:14:23

-- zauważ, że nie można użyć aliasu nad tabelą, gdzie trzeba usunąć

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
 -3
Author: Hernan Torres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-13 18:11:08