带有内部连接和限制的mysql删除

Posted

技术标签:

【中文标题】带有内部连接和限制的mysql删除【英文标题】:mysql delete with inner joins and limit 【发布时间】:2015-02-05 13:27:42 【问题描述】:

这是我能想到的唯一方法,我收到关于限制的错误。我正在尝试在 while 循环中分块删除,因为结果总数可能非常大。

第一个计数语句工作正常。它是第二个 delete 语句,它没有。我猜是因为连接和/或使用限制。如何在加入时限制删除?

//find total count to delete
$stmt = $db->prepare("
    SELECT
        COUNT(*)
    FROM app_logs
    INNER JOIN users
        ON users.user_id = app_logs.user_id
    INNER JOIN computers
        ON computers.computer_id = users.computer_id AND computers.account_id != :account
    WHERE app_logs.timestamp < :cutoff_time
");

$binding = array(
    'account' => 2,
    'cutoff_time' => strtotime('-3 months')
);

$stmt->execute($binding);

//get total results count from above
$found_count = $stmt->fetch(PDO::FETCH_COLUMN, 0);

echo $found_count; //ex. 15324

//delete rows
$stmt = $db->prepare("
    DELETE
    FROM app_logs
    INNER JOIN users
        ON users.user_id = spc_app_logs.user_id
    INNER JOIN computers
        ON computers.computer_id = users.computer_id AND computers.account_id != :account       
    WHERE app_logs.timestamp < :cutoff_time
    LIMIT :limit
");

$binding = array(
    'account' => 2,
    'cutoff_time' => strtotime('-3 months'),
    'limit' => 2000
);

while($found_count > 0)

    $stmt->execute($binding);

    $found_count = $found_count - $binding['limit'];

【问题讨论】:

【参考方案1】:

作为mentioned in the docs 和in this answer,LIMIT 不能与DELETE + JOIN 一起使用

如果您需要以某种方式限制删除,只需为 DELETE 语句创建条件,它将模拟您的 LIMIT 部分。例如,您可以按照以下步骤操作:

    从要从中删除值的查询中获取最小和最大行的 ID(比如说:10 和 200) 然后选择 bordering ids 模仿您的限制(因此对于限制 50,边界 id 可以是 50、100、150、200) 然后,对于每个bordering id,查询一个DELETE 语句,其中WHERE 具有AND id &lt;= ?,并将每个bordering id 放在@987654330 的位置@。 因此您最终会得到 4 个类似的查询,每个查询都会删除特定范围 (10-50]、(50, 100] 等的 id)。

希望这会有所帮助。

【讨论】:

以上是关于带有内部连接和限制的mysql删除的主要内容,如果未能解决你的问题,请参考以下文章

mysql删除字段数据,Java面试真题精选

sql删除使用内连接超过3个表

MySQL 更新和删除

mysql之临时表

带有 WHERE 子句的 MySql 内部连接 ​​[关闭]

从有限制的表中删除(mySQL)