sql >> Databasteknik >  >> RDS >> Mysql

Ta bort en rad med inre koppling

Överväg att köra DELETE...INNER JOIN och DELETE med subquery-villkor och undvik PHP-frågehämtningslooping med if/else eftersom logiken verkar vara följande:

  1. ta bort alla kommentatorers profil och kommentarer om han/hon bara har en kommentar
  2. ta bort endast kommentatorns kommentarer om han/hon har flera (dvs fler än en) kommentarer.

Och ja, alla tre DELETE kan köras samtidigt över alla id eftersom ömsesidigt uteslutande villkor är placerade mellan de två första och sista. Därför påverkar antingen de två första raderna eller den sista raderna per iteration. De opåverkade raderna kommer att radera noll rader från endera tabellen.

Även enkla kommentarer poster tas bort först eftersom den här tabellen kan ha en främmande nyckelrestriktion med kommentator på grund av dess en-till-många-relation. Slutligen, nedan antar kommentar ID skickas till loop (inte kommentator id).

PHP (med hjälp av parametrering, förutsatt att $conn är ett mysqli-anslutningsobjekt)

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

Alternativt, för en DRY-er-metod, loopa SQL-satser i en array:

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



  1. Hur man utökar kommaseparerade fält till flera rader i MySQL

  2. Vill lagra objekt i MySQL-databas

  3. Varför jag får olika resultat när jag använder innerfog

  4. MySQL får rekordantal per timme, även timmar utan rekord