mysql删除内部联接和限制

时间:2015-02-05 13:27:42

标签: mysql delete-row

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

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

//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'];
}

2 个答案:

答案 0 :(得分:0)

作为mentioned in the docsin this answer LIMIT不能与DELETE + JOIN 一起使用。

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

  1. 从要删除的查询中获取最小和最大行ID(例如:10和200)
  2. 然后选择接壤的ids 模仿你的限制(所以对于限制50,接壤的id可以是50,100,150,200)
  3. 然后,对于每个边界ID ,查询DELETE语句WHERE AND id <= ?,并将每个边框ID 代替?
  4. 所以你最终会得到4个类似的查询,每个查询都会删除某个范围内的ID(10-50),(50,100)等。
  5. 希望这有帮助。

答案 1 :(得分:-1)

在删除查询中有多个表时,您需要告诉DB要删除哪些表。您可以在第一行

中执行此操作
DELETE app_logs
FROM app_logs
INNER JOIN users ON ...
INNER JOIN computers ON ...