Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Löschen einer Zeile mit Inner Join

Erwägen Sie, DELETE...INNER JOIN auszuführen und DELETE mit Unterabfragebedingungen und vermeiden Sie PHP-Abfrageschleifen mit if/else da die Logik folgende zu sein scheint:

  1. Löschen Sie das Profil und die Kommentare eines jeden Kommentators, wenn er/sie nur einen Kommentar hat
  2. Löschen Sie nur die Kommentare des Kommentators, wenn er/sie mehrere (d. h. mehr als einen) Kommentar hat.

Und ja, alle drei DELETE kann gleichzeitig über alle IDs ausgeführt werden, da sich gegenseitig ausschließende Bedingungen zwischen den ersten beiden und der letzten platziert werden. Daher wirken sich entweder die ersten beiden auf die Zeilen oder die letzte auf die Zeilen pro Iteration aus. Die nicht betroffenen löschen null Zeilen aus jeder Tabelle.

Auch einfache Kommentare Datensätze werden zuerst gelöscht, da diese Tabelle möglicherweise eine Fremdschlüsseleinschränkung mit Kommentar hat aufgrund seiner Eins-zu-Viele-Beziehung. Schließlich wird unten von Kommentar ausgegangen IDs werden in die Schleife übergeben (nicht commentor id).

PHP (unter Verwendung von Parametrierung, vorausgesetzt, $conn ist ein mysqli-Verbindungsobjekt)

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

Alternativ können Sie für einen DRY-er-Ansatz SQL-Anweisungen in einem Array durchlaufen:

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