sql >> Database >  >> RDS >> Mysql

Een rij met inner join verwijderen

Overweeg om DELETE...INNER JOIN . uit te voeren en DELETE met subquery-voorwaarden en vermijd PHP-query fetch-looping met if/else aangezien de logica als volgt lijkt te zijn:

  1. verwijder het profiel en de opmerkingen van een commentator als hij/zij maar één opmerking heeft
  2. verwijder alleen de opmerkingen van de commentator als hij/zij meerdere (d.w.z. meer dan één) opmerkingen heeft.

En ja, alle drie DELETE kan tegelijkertijd over alle id's worden uitgevoerd, aangezien wederzijds uitsluitende voorwaarden worden geplaatst tussen de eerste twee en de laatste. Daarom beïnvloeden de eerste twee rijen of de laatste rijen per iteratie. De niet-beïnvloede(n) zullen nul rijen uit beide tabellen verwijderen.

Ook eenvoudige opmerkingen records worden eerst verwijderd omdat deze tabel mogelijk een externe sleutelbeperking heeft met commentor vanwege de een-op-veel relatie. Ten slotte wordt hieronder uitgegaan van commentaar ID's worden doorgegeven aan de lus (niet commentator id).

PHP (met behulp van parametrering, ervan uitgaande dat $conn een mysqli-verbindingsobject is)

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

Als alternatief, voor een DRY-er-aanpak, loop SQL-instructies in een 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. Asynchrone DBappender met logback

  2. com.microsoft.sqlserver.jdbc.SQLServerException:de TCP/IP-verbinding met de host localhost, poort 1433 is mislukt

  3. Waarom is deze query de eerste keer traag nadat ik de service start?

  4. Hoe gewijzigde gegevens in de database bijwerken met behulp van JTable?