删除内部联接的行

时间:2017-11-11 13:48:42

标签: php mysql sql join

我创建了两个表, simplecomments 评论员,并将它们与INNER JOIN相关联。

  • 简单评论是每个评论者的详细信息,涉及他们的评论,reg_date,commentorid等......
  • 评论者是评论者的个人信息,其中包含以下列:id,name,email ..

我已经成功加入了它们,但是我发现很难从连接表中删除它。

我想让它像这样的逻辑:

  1. 如果,评论员的最后一行称为--let说A--然后从表中删除他/她的评论详细信息和A他/她自己。

  2. 其他如果A已经多次发表评论,发表不同评论,请删除他/她的评论详情,但是由于A还有其他评论,所以请保留他/她的个人信息。

  3. 这就是我的成就:

    if (!empty($_POST["delete"]))
    {
        foreach ($_POST["delete"] as $key => $value) 
        {
            $resultid = $conn->query("SELECT commentorid FROM `simplecomments` WHERE id=".$value);
            $rowid = $resultid->fetch_assoc();
    
            $outputdelete = $rowid["name"] . " has been deleted" . "<br>";
    
            $deletedname = $deletedname.$outputdelete;
            $RES = mysql_num_rows($resultid);
            $counter = 0;
                while($row = $RES)
                {
                   //IF IT'S LAST ROW, DELETE COMMENTOR AND HIS/HER COMMENTDETAILS 
                    if(++$counter == $results) {
                        $resultid = $conn->query("DELETE FROM `commentor`");
                    }
                    //ELSE JUST DELETE HIS/HER COMMENTDETAILS, LET HIS/HER INFO REMAIN
                    else{
                        $resultid = $conn->query("DELETE FROM `simplecomments` WHERE id=".$value);
                    } 
                }
        }
    
    }
    

    但是代码不起作用。我收到一个错误:

      

    警告:mysql_num_rows()期望参数1为resource [..] ...

1 个答案:

答案 0 :(得分:2)

考虑使用子查询条件运行DELETE...INNER JOINDELETE,并避免使用if/else进行PHP查询获取循环,因为逻辑似乎如下:

  1. 删除任何评论员的个人资料和评论,如果他/她只有一个评论
  2. 如果他/她有多个(即多个)评论,则只删除评论员的评论。
  3. 是的,所有三个DELETE都可以在所有ID上同时运行,因为在前两个和最后一个之间存在互斥条件。因此,前两个影响行,或者最后一个影响每次迭代的行。未受影响的人将从任一表中删除零行。

    此外,首先删除 simplecomments 记录,因为由于其一对多关系,此表可能与 commentor 具有外键约束。最后,下面假设 comment id传递给循环(不是 commentor 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();
       }
    }