Mysql
 sql >> база данни >  >> RDS >> Mysql

Изтриване на ред с вътрешно съединение

Помислете за изпълнение на DELETE...INNER JOIN и DELETE с условни условия на подзаявка и избягване на цикъл на извличане на PHP заявка с if/else тъй като логиката изглежда е следната:

  1. изтрийте всеки профил и коментари на коментиращ, ако той/тя има само един коментар
  2. изтрийте само коментарите на коментиращия, ако той/тя има няколко (т.е. повече от един) коментара.

И да, и трите DELETE може да се изпълнява едновременно за всички идентификатори, тъй като между първите две и последния са поставени взаимно изключващи се условия. Следователно или първите два засягат редовете, или последният засяга редовете на итерация. Незасегнатите ще изтрият нула редове от която и да е таблица.

Освен това прости коментари записите се изтриват първо, тъй като тази таблица може да има ограничение за външен ключ с коментатор поради връзката си едно към много. И накрая, по-долу предполага коментар идентификаторите се предават в цикъл (не в коментатор id).

PHP (използване на параметризация, като се приеме, че $conn е обект за свързване на 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();
}

Като алтернатива, за подход DRY-er, циклични SQL изрази в масив:

$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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Добре ли е да използвате htmlspecialchars() преди вмъкване в MySQL?

  2. Условно в MYSQL клауза where

  3. MySQL, разделен по времеви диапазон

  4. doctrine:schema:update не зачита реда на колоните

  5. Mysql е твърде бавен при проста заявка между две таблици