sql >> Base de Datos >  >> RDS >> Mysql

Eliminación de una fila con combinación interna

Considere ejecutar DELETE...INNER JOIN y DELETE con condicionales de subconsultas y evitar bucles de recuperación de consultas de PHP con if/else ya que la lógica parece ser la siguiente:

  1. eliminar el perfil y los comentarios de cualquier comentarista si solo tiene un comentario
  2. eliminar solo los comentarios del comentarista si tiene varios (es decir, más de uno) comentarios.

Y sí, los tres DELETE se puede ejecutar al mismo tiempo en todos los identificadores, ya que se establecen condiciones mutuamente excluyentes entre los dos primeros y el último. Por lo tanto, los dos primeros afectan las filas o el último afecta las filas por iteración. Los no afectados eliminarán cero filas de cualquiera de las tablas.

Además, comentarios simples los registros se eliminan primero ya que esta tabla puede tener una restricción de clave externa con commentor debido a su relación de uno a muchos. Finalmente, a continuación se asume comentario los identificadores se pasan al bucle (no a comentar) identificación).

PHP (usando parametrización, asumiendo que $conn es un objeto de conexión mysqli)

foreach ($_POST["delete"] as $key => $value) {

   // DELETE COMMENTS AND THEN PROFILE FOR COMMENTORS WITH ONE POST    
   $sql = "DELETE FROM `simplecomments` s 
           WHERE s.id = ?
             AND (SELECT COUNT(*) FROM `simplecomments` sub
                  WHERE sub.commentorid = s.commentorid) = 1";
   $stmt = $conn->prepare($sql);
   $stmt->bind_param("i", $value);
   $stmt->execute();
   $stmt->close();

   $sql = "DELETE c.* FROM `simplecomments` c 
           INNER JOIN `simplecomments` s ON s.commentorid = c.id
           WHERE s.id = ?
             AND (SELECT COUNT(*) FROM `simplecomments` sub
                  WHERE sub.commentorid = s.commentorid) = 1";
   $stmt = $conn->prepare($sql);
   $stmt->bind_param("i", $value);
   $stmt->execute();
   $stmt->close();


   // DELETE COMMENTS FOR COMMENTORS WITH MULTIPLE POSTS BUT KEEP PROFILE
   $sql = "DELETE FROM `simplecomments` s
           WHERE s.id = ?
             AND (SELECT COUNT(*) FROM `simplecomments` sub
                  WHERE sub.commentorid = s.commentorid) > 1";    
   $stmt = $conn->prepare($sql);
   $stmt->bind_param("i", $value);
   $stmt->execute();
   $stmt->close();
}

Alternativamente, para un enfoque DRY-er, repita las declaraciones SQL en una matriz:

$sqls = array(
           0 => "DELETE FROM `simplecomments` s WHERE s.id = ? AND (SELECT COUNT(*) FROM `simplecomments` sub WHERE sub.commentorid = s.commentorid) = 1",
           1 => "DELETE c.* FROM `simplecomments` c INNER JOIN `simplecomments` s ON s.commentorid = c.id WHERE s.id = ? AND (SELECT COUNT(*) FROM `simplecomments` sub WHERE sub.commentorid = s.commentorid) = 1",
           2 => "DELETE FROM `simplecomments` s WHERE s.id = ? AND (SELECT COUNT(*) FROM `simplecomments` sub WHERE sub.commentorid = s.commentorid) > 1"
        );

foreach ($_POST["delete"] as $key => $value) {
   foreach($sqls as $sql) {
       $stmt = $conn->prepare($sql);
       $stmt->bind_param("i", $value);
       $stmt->execute();
       $stmt->close();
   }
}