Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Excluindo uma linha com junção interna


Considere executar DELETE...INNER JOIN e DELETE com condicionais de subconsulta e evite o loop de busca de consulta PHP com if/else pois a lógica parece ser a seguinte:
  1. exclua o perfil e os comentários de qualquer comentarista se ele tiver apenas um comentário
  2. exclua apenas os comentários do comentarista se ele tiver vários (ou seja, mais de um) comentários.

E sim, todos os três DELETE pode ser executado ao mesmo tempo em todos os ids, pois as condições mutuamente exclusivas são colocadas entre os dois primeiros e o último. Portanto, os dois primeiros afetam as linhas ou o último afeta as linhas por iteração. O(s) não afetado(s) excluirá zero linhas de qualquer tabela.

Além disso, comentários simples os registros são excluídos primeiro, pois esta tabela pode ter uma restrição de chave estrangeira com commentador devido à sua relação um-para-muitos. Finalmente, abaixo assume comentário ids são passados ​​em loop (não commentador Eu iria).

PHP (usando parametrização, assumindo que $conn é um objeto de conexão 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();
}

Como alternativa, para uma abordagem DRY-er, faça um loop de instruções SQL em uma 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();
   }
}