sql >> Databáze >  >> RDS >> Mysql

Odstranění řádku s vnitřním spojením

Zvažte spuštění DELETE...INNER JOIN a DELETE s podmínkami poddotazu a vyhněte se opakování načítání dotazů PHP pomocí if/else protože logika se zdá být následující:

  1. smazat profil a komentáře každého komentujícího, pokud má pouze jeden komentář
  2. Smažte pouze komentáře komentujícího, pokud má více (tj. více než jeden) komentářů.

A ano, všechny tři DELETE lze spustit současně napříč všemi ID, protože mezi prvními dvěma a posledním jsou umístěny vzájemně se vylučující podmínky. Proto buď první dva ovlivní řádky, nebo poslední ovlivní řádky na iteraci. Neovlivněné jedničky odstraní nula řádků z obou tabulek.

Také jednoduché komentáře záznamy jsou odstraněny jako první, protože tato tabulka může mít omezení cizího klíče s komentátorem kvůli jeho vztahu jeden k mnoha. Konečně, níže předpokládá komentář ID jsou předávána do smyčky (nikoli komentátor id).

PHP (pomocí parametrizace, za předpokladu, že $conn je objekt připojení 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();
}

Alternativně pro přístup DRY-er opakujte příkazy SQL v poli:

$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. Spouštění skriptů souborů SQL z programu Java

  2. Jak vypsat dostupné instance serverů SQL pomocí SMO v C#?

  3. db2 ekvivalent MySql REPLACE INTO

  4. pomocí pl/sql, jak otevřu adresář?