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.

mehdi
fuente

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'
Eric
fuente
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 .

kiwi enojado
fuente
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.

Quassnoi
fuente
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í .

Mike Trpcic
fuente
7

no es necesario UNIRSE:

DELETE m, um FROM messages m, usersmessages um

WHERE m.messageid = 1 

AND m.messageid = um.messageid 
Fred Yates
fuente
6
DELETE message.*, usersmessage.* from users, usersmessage WHERE message.messageid=usersmessage.messageid AND message.messageid='1'
johan
fuente
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
Mark Angelo Pascual
fuente
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'
Amit
fuente
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. :)

John Oliver Amurao
fuente
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';
Vidya
fuente
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

Midz Elwekil
fuente
Esto bien podría ayudar a alguien ... aunque parece PHP, no creo que eso esté necesariamente dentro del alcance de la pregunta :)
Tom Bush