Mysql
 sql >> Base de données >  >> RDS >> Mysql

Supprimer une ligne avec jointure interne

Envisagez d'exécuter DELETE...INNER JOIN et DELETE avec des conditions de sous-requête et éviter les boucles de récupération de requête PHP avec if/else car la logique semble être la suivante :

  1. supprimer le profil et les commentaires de tout commentateur s'il n'a qu'un seul commentaire
  2. supprimer uniquement les commentaires du commentateur s'il a plusieurs commentaires (c'est-à-dire plus d'un).

Et oui, les trois DELETE peut être exécuté en même temps sur tous les identifiants puisque des conditions mutuellement exclusives sont placées entre les deux premiers et le dernier. Par conséquent, les deux premiers affectent les lignes ou le dernier affecte les lignes par itération. La ou les lignes non affectées supprimeront zéro ligne de l'une ou l'autre des tables.

Aussi, commentaires simples les enregistrements sont supprimés en premier car cette table peut avoir une contrainte de clé étrangère avec commentaire en raison de sa relation un-à-plusieurs. Enfin, ci-dessous suppose commentaire les identifiants sont passés en boucle (pas commentateur identifiant).

PHP (en utilisant le paramétrage, en supposant que $conn est un objet de connexion 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();
}

Sinon, pour une approche DRY-er, bouclez les instructions SQL dans un tableau :

$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();
   }
}