Eliminar de dos tablas en una consulta


82

Tengo dos tablas en MySQL

#messages table  : 
messageid
messagetitle 
.
.

#usersmessages table 
usersmessageid 
messageid
userid
.
.

Ahora, si quiero eliminar de la tabla de mensajes, está bien. Pero cuando elimino mensaje por messageid, el registro todavía existe en usersmessage y tengo que eliminar de estas dos tablas a la vez.

Usé la siguiente consulta:

DELETE FROM messages LEFT JOIN usersmessages USING(messageid) WHERE messageid='1' ; 

Entonces pruebo

   DELETE FROM messages , usersmessages 
   WHERE messages.messageid = usersmessages.messageid 
   and messageid='1' ; 

Pero estas dos consultas no están cumpliendo esta tarea.

Respuestas:


135

¿No puedes separarlos con un punto y coma?

Delete from messages where messageid = '1';
Delete from usersmessages where messageid = '1'

O

Solo use INNER JOINcomo abajo

DELETE messages , usersmessages  FROM messages  INNER JOIN usersmessages  
WHERE messages.messageid= usersmessages.messageid and messages.messageid = '1'

1
¿Qué pasa si quiero poner este código en un bucle? Sé que puedo poner el punto y coma absolutamente.
— mehdi

1
Se puede poner en un bucle. Puede hacerlo mediante programación y enviar la identificación del mensaje como parámetro. Mientras no sigas enviándole la misma identificación, no se eliminará una y otra vez.
— Eric

4
Si hace esto en dos consultas, realmente debería envolverlo en una transacción. En cuanto a ejecutar consultas de eliminación en un bucle, es mejor que formule una sola consulta para realizar todas las eliminaciones.
— JohnFx

1
Consulte otro ejemplo de consulta de eliminación con uniones bennadel.com/blog/…
— Babar

19
No funciona con SQL Server: sintaxis incorrecta cerca de ','.
— Paul-Sebastian Manole

44
DELETE a.*, b.* 
FROM messages a 
LEFT JOIN usersmessages b 
ON b.messageid = a.messageid 
WHERE a.messageid = 1

translation: eliminar de la tabla de mensajes donde messageid = 1, si la tabla uersmessages tiene messageid = messageid de la tabla de mensajes , elimina esa fila de la tabla uersmessages .


comentario para todos: como se muestra en este ejemplo, es importante especificar en qué tabla debe funcionar la eliminación. Gran publicación @angry_kiwi
— Raphael_b

Solo tenía que cambiar el orden, DESDE los mensajes de los usuarios b LEFT JOIN mensajes a
— Pablo

15

Deberías crear un FOREIGN KEYcon ON DELETE CASCADE:

ALTER TABLE usersmessages
ADD CONSTRAINT fk_usermessages_messageid
FOREIGN KEY (messageid)
REFERENCES messages (messageid)
ON DELETE CASCADE

, o hacerlo usando dos consultas en una transacción:

START TRANSACTION;;

DELETE
FROM    usermessages
WHERE   messageid = 1

DELETE
FROM    messages
WHERE   messageid = 1;

COMMIT;

Sin InnoDBembargo, la transacción solo afecta a las tablas.


3
¡ Puede eliminar de varias tablas en una consulta! dev.mysql.com/doc/refman/5.0/en/delete.html
— txwikinger

¡sí tu puedes! Pero para mí ... es más fácil hacer lo que decía mi respuesta.
— Eric

Agregué la cascada en una mesa similar mía. Cuando intenté eliminar solo de 1 tabla, eliminé el registro y dejó huérfano al relacionado. ¿De qué sirve la restricción?
— Barfoon

@barfoon: ¿es tu mesa InnoDB?
— Quassnoi

@Quassnoi ¡Ups! Definitivamente pensé que era, qué tontería. Todas las tablas son MyISAM. ¿Puedo cambiarlos todos sobre la marcha con datos en ellos? ¿O hay problemas con eso?
— barfoon

7

Tienes dos opciones:

Primero, haga dos declaraciones dentro de una transacción:

BEGIN;
  DELETE FROM messages WHERE messageid = 1;
  DELETE FROM usermessages WHERE messageid = 1;
COMMIT;

O bien, podría tener ON DELETE CASCADE configurado con una clave externa. Este es el mejor enfoque.

CREATE TABLE parent (
  id INT NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE child (
  id INT, parent_id INT,
  FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
);

Puede leer más sobre ON DELETE CASCADE aquí .


7

no es necesario UNIRSE:

DELETE m, um FROM messages m, usersmessages um

WHERE m.messageid = 1 

AND m.messageid = um.messageid 

6
DELETE message.*, usersmessage.* from users, usersmessage WHERE message.messageid=usersmessage.messageid AND message.messageid='1'

6

Al OP simplemente le faltan los alias de la tabla después de la eliminación

DELETE t1, t2 
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id 
WHERE t1.id = some_id

3
Gracias por tu respuesta. Sería más útil si intenta explicar por qué esto funcionaría y por qué la solución OP no lo hizo.
— DdW

1

Prueba esto por favor

DELETE FROM messages,usersmessages

USING messages

INNER JOIN usermessages on (messages.messageid = usersmessages.messageid)

WHERE messages.messsageid='1'

0

Prueba esto..

DELETE a.*, b.*  
FROM table1 as a, table2 as b  
WHERE a.id=[Your value here] and b.id=[Your value here]

Dejo idcomo muestra una columna.

Me alegro de que esto ayude. :)


Para que los asterikses ( *) se representen correctamente, debe sangrar la consulta con 4 espacios al frente.
— Al.G.

0

También puede usar así, para eliminar un valor particular cuando ambas columnas tienen 2 o muchas del mismo nombre de columna.

DELETE project , create_test  FROM project INNER JOIN create_test
WHERE project.project_name='Trail' and  create_test.project_name ='Trail' and project.uid= create_test.uid = '1';

0

hay otra forma que no se menciona aquí (todavía no probé completamente su rendimiento), puede establecer una matriz para todas las tablas -> filas que desea eliminar como se muestra a continuación

// set your tables array
$array = ['table1', 'table2', 'table3'];


// loop through each table
for($i = 0; $i < count($array); $i++){

 // get each single array
 $single_array = $array[$i];

 // build your query
 $query = "DELETE FROM $single_array WHERE id = 'id'";

 // prepare the query and get the connection
 $data = con::GetCon()->prepare($query);

 // execute the action
 $data->execute();
}

entonces podría redirigir al usuario a la página de inicio.

header('LOCATION:' . $home_page);

Espero que esto ayude a alguien :)

Gracias


Esto bien podría ayudar a alguien ... aunque parece PHP, no creo que eso esté necesariamente dentro del alcance de la pregunta :)
— Tom Bush
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.