Eliminar con una sola consulta sql

NeB1

Hola buenas!

Sigo con mis dudas SQL. Tengo 3 tablas, una es la tabla necesaria para hacer la relación de n a m elementos entre las dos otras tablas, es decir:

TABLA preguntas (id,pregunta)
TABLA respuestas (id,respuestas)
TABLA preguntasRespuestas (idPreguntas,idRespuestas)

Como hago para, teniendo la ID de la pregunta, eliminar todas las respuestas asociadas a esa pregunta con una única consulta SQL.?

Siempre hacía esto con varias consultas ayudandome en exceso del lenguaje que hubiese por detrás, PHP, ASP o el que fuese, pero quiero empezar a aprender a hacerlo bien...

Shendraf

¿Te refieres a esto?:

DELETE FROM preguntasRespuestas 
WHERE idPreguntas = :idPregunta

¿O te refieres a que debe borrar también los registros de la tabla "respuestas"?

Elektr0_ddr

Según si tienes en la base de datos declarados los DELETE ON CASCADE o con trigger.
Mediante SQL siempre he usado varias consultas, me extraña que se puedan borrar de varias tablas en una sola, pero que te responda algun experto mejor xD

Shendraf

Como bien dice #3, al tener las tablas interrelacionadas por ID lo ideal es que hagas uso del ON DELETE CASCADE. Si lo que quieres es eliminar registros de varias tablas a la vez, lo suyo es que escribas esas sentencias en un procedimiento PL/SQL

TBT

qué quieres hacer?

tabla p (id, p)
1 que hora es?
2 hace frio?
3 tienes calor?

tabla r (id, r)
1 si
2 no
3 las 3
4 las 4

tabla pr (pid, rid)
1 3
1 4
2 1
2 2
3 1
3 2

dices que si quieres borrar las respuestas de "hace frio?" que te borre de R "si" y "no"? o quieres que las borre sólo si no hay más preguntas con esas respuestas? (que al borrar "hace frio?" no te las borre, pero con "hace calor?" sí).

NeB1

En principio me gustaría como hacer, si tengo la ID de una pregunta, mirar en preguntasRespuestas todas las respuestas que esta pregunta tiene asociada, y dichas respuestas eliminarlas de la tabla respuestas.

no sé si me explico bien...

Ejemplo!!

PREGUNTA ID 1: ¿Que tiempo hace en valencia?

RESPUESTAS ASOCIADAS:

RESPUESTA ID 1: Buen tiemp

RESPUESTA ID 2: Mal tiempo

RESPUESTA ID 3: ni idea

Sabiendo que tengo la ID 1 de pregunta, eliminar todas las respuestas asociadas, en este caso, la 1, la 2 y la 3.

eXtreM3

Lo que tienes que hacer es crear las tablas de manera InnoDB. De esta manera:

CREATE TABLE usuarios(
idUsuario INT AUTO_INCREMENT PRIMARY KEY,
nick VARCHAR(250) NOT NULL,
password VARCHAR(250) NOT NULL
)ENGINE=InnoDB;

Vale?? ahora pongamos otra tabla, por ejemplo

CREATE TABLE temasForo(
idTema INT AUTO_INCREMENT PRIMARY KEY,
idUsuario INT,
CONSTRAINT fk_temas1 FOREIGN KEY (idUsuario) REFERENCES usuarios (idUsuario) ON DELETE CASCADE
)ENGINE=InnoDB;

Es un ejemplo muy chorra vale? pero haciendo eso, tendrás las tablas directamente relacionadas.

Si eliminas un usuario, se eliminarán todos los temas que haya creado ese usuario.

Resumiendo, el truco es crear las tablas mediante InnoDB.

Saludos ;)

SiNSoNiDo

A mi lo que no me convence es que elimine físicamente, no uses DELETE, añade un campo llamado "activo" con valores si o no y haz un UPDATE poniéndolo a no para eliminar los registros.
De eliminar físicamente de una BD nunca sale nada bueno...

eXtreM3

#8 y para qué quieres un millón de datos no activos si no los vas a usar? :\

Se supone que si vas a borrar algo es porque eres el administrador de lo que vas a borrar, si tomas la determinación de borrar un registro es porque realmente piensas que no lo vas a necesitar nunca más.

Pongamos el ejemplo de un foro. Un usuario crea un tema cuyo contenido rompe con la política de la web y antes de que algun moderador vea el hilo, ha habido 10.000 respuestas. Llega el moderador y, logicamente, elimina el hilo. Para qué quieres guardar esas 10.000 respuestas??? no tiene sentido alguno, piénsalo ;)

SiNSoNiDo

#9, #1 decía que quería hacer las cosas bien. Imagínate que aun siendo tu administrador hay otros que administran contigo la BD y se cargan sin querer algo que no debían de cargarse, siempre podrías recuperarlo. O si por error hago click donde no debía y elimino la pregunta y respuestas que no quería eliminar no tendría forma de recuperarlo.

eXtreM3

Para eso existen los backups, como tú dices si quieres hacer algo bien, intégrale un auto-backup cada X tiempo, que te vuelque los nuevos registros para no tener que volcar y sobreescribir todo.

Sé lo que quieres decir, y en realidad no es algo inválido, ya que haciendo una consulta eficiente se conseguiria el mismo efecto, lo único negativo es guardar valores inservibles, a priori, en tu bd.

Yo me he limitado a contestar y resolverle la duda a #1, que por lo que he entendido, lo que él hacia POR CÓDIGO era lo siguiente:

  • DETELE FROM tabla_secundaria WHERE id = id
  • DELETE FROM tabla_primaria WHERE id = id

Se puede ahorrar la 1ª consulta creando las tablas InnoDB, para que queden relacionadas. Por lo cual sólo tendria que escribir una consulta:

  • DELETE FROM tabla_primaria WHERE id = id; y se borrarían todos los registros de la tabla secundaria automaticamente.

Saludos again ^^

bLaKnI

Dejaros de gilipolleces rocambolescas:

  • Declara claves foraneas donde toca, y usa "ON DELETE CASCADE".

NADA MAS.
Y si, InnoDB ya que MyISAM no acepta claves foraneas ni transacciones ni...

JuAn4k4

Es mejor dejarlo a inactivo y si te falta espacio hacer delete de lo que esta inactivo (en cascada aqui si), y si ya eres tiquismiquis tener la fecha de cuando se quedo inactivo y borrar los más antiguos inactivos.

Pero vamos que lo que quieres hacer tu es un "on delete cascade".

Usuarios habituales

  • bLaKnI
  • eXtreM3
  • SiNSoNiDo
  • NeB1
  • TBT
  • Shendraf
  • Elektr0_ddr