update stackoverflow register query from example delete and mysql sql subquery sql-delete in-subquery

stackoverflow - MySQL DELETE FROM con subconsulta como condición



mysql update delete (7)

¿No es la cláusula "in" en el delete ... where, extremadamente ineficiente, si va a haber una gran cantidad de valores devueltos desde la subconsulta? No estoy seguro de por qué no se uniría interna (o derecha) a la tabla original desde la subconsulta en la ID para eliminar, en lugar de a nosotros el "en (subconsulta)".

DELETE T FROM Target AS T RIGHT JOIN (full subquery already listed for the in() clause in answers above) ` AS TT ON (TT.ID = T.ID)

Y tal vez se responde en el "MySQL no lo permite", sin embargo, está funcionando bien para mí siempre que me asegure de aclarar por completo qué eliminar (ELIMINAR T DE COMO AS T). Eliminar con Join en MySQL aclara el problema DELETE / JOIN.

Estoy tratando de hacer una consulta como esta:

DELETE FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN ( SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015 );

Como probablemente pueda decir, quiero eliminar la relación padre a 1015 si el mismo tid tiene otros padres. Sin embargo, eso me da un error de sintaxis:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''AS th WHERE th.parent = 1015 AND th.tid IN ( SELECT DISTINCT(th1.tid) FROM ter'' at line 1

Revisé la documentación y ejecuté la subconsulta por sí mismo, y parece que todo está pendiente. ¿Alguien puede descubrir lo que está mal aquí?

Actualización : Como se explica a continuación, MySQL no permite que la tabla que está eliminando se use en una subconsulta para la condición.



El alias se debe incluir después de la palabra clave DELETE :

DELETE th FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN ( SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015 );


Me acerqué a esto de una manera ligeramente diferente y funcionó para mí;

Necesitaba eliminar secure_links de mi tabla que hacía referencia a la tabla de conditions donde ya no quedaban filas de condiciones. Un guión de limpieza básicamente. Esto me dio el error: no puede especificar la tabla de destino para eliminar.

Así que, buscando inspiración aquí, se me ocurrió la siguiente pregunta y funciona muy bien. Esto se debe a que crea una tabla temporal sl1 que se utiliza como referencia para el DELETE.

DELETE FROM `secure_links` WHERE `secure_links`.`link_id` IN ( SELECT `sl1`.`link_id` FROM ( SELECT `sl2`.`link_id` FROM `secure_links` AS `sl2` LEFT JOIN `conditions` ON `conditions`.`job` = `sl2`.`job` WHERE `sl2`.`action` = ''something'' AND `conditions`.`ref` IS NULL ) AS `sl1` )

Funciona para mi.


No puede especificar la tabla de destino para eliminar.

Una solución

create table term_hierarchy_backup (tid int(10)); <- check data type insert into term_hierarchy_backup SELECT DISTINCT(th1.tid) FROM term_hierarchy AS th1 INNER JOIN term_hierarchy AS th2 ON (th1.tid = th2.tid AND th2.parent != 1015) WHERE th1.parent = 1015; DELETE FROM term_hierarchy AS th WHERE th.parent = 1015 AND th.tid IN (select tid from term_hierarchy_backup);


Para otros que buscan eliminar esta pregunta mientras usan una subconsulta, les dejo este ejemplo para burlar a MySQL (incluso si algunas personas parecen pensar que no se puede hacer):

DELETE e.* FROM tableE e WHERE id IN (SELECT id FROM tableE WHERE arg = 1 AND foo = ''bar'');

te dará un error:

ERROR 1093 (HY000): You can''t specify target table ''e'' for update in FROM clause

Sin embargo, esta consulta:

DELETE e.* FROM tableE e WHERE id IN (SELECT id FROM (SELECT id FROM tableE WHERE arg = 1 AND foo = ''bar'') x);

funcionará bien

Query OK, 1 row affected (3.91 sec)

Envuelva su subconsulta en una subconsulta adicional (aquí nombrada x) y MySQL hará lo que le pida.


Si desea hacer esto con 2 consultas, siempre puede hacer algo similar a esto:

1) tomar identificadores de la mesa con:

SELECT group_concat(id) as csv_result FROM your_table WHERE whatever = ''test'' ...

Luego copie el resultado con el mouse / teclado o el lenguaje de programación a XXX a continuación:

2) DELETE FROM your_table WHERE id IN ( XXX )

Tal vez podrías hacer esto en una consulta, pero esto es lo que prefiero.