Mysql
 sql >> Database >  >> RDS >> Mysql

Eliminazione di una riga con inner join

Prendi in considerazione l'esecuzione di DELETE...INNER JOIN e DELETE con i condizionali delle sottoquery ed evita il ciclo di recupero delle query PHP con if/else poiché la logica sembra essere la seguente:

  1. elimina il profilo e i commenti di qualsiasi commentatore se ha un solo commento
  2. elimina solo i commenti del commentatore se questi ha più (cioè più di uno) commenti.

E sì, tutti e tre DELETE può essere eseguito contemporaneamente su tutti gli ID poiché le condizioni che si escludono a vicenda sono poste tra i primi due e l'ultimo. Pertanto, le prime due influiscono sulle righe o l'ultima incide sulle righe per iterazione. Quelli non interessati elimineranno zero righe da una delle due tabelle.

Inoltre, commenti semplici i record vengono eliminati per primi poiché questa tabella potrebbe avere un vincolo di chiave esterna con commentor a causa della sua relazione uno-a-molti. Infine, di seguito si presuppone un commento gli ID vengono passati al ciclo (non commentor id).

PHP (usando la parametrizzazione, supponendo che $conn sia un oggetto di connessione 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();
}

In alternativa, per un approccio DRY-er, esegui il ciclo delle istruzioni SQL in un 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();
   }
}