带有内部连接和限制的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 <= ?
,并将每个bordering id 放在@987654330 的位置@。
因此您最终会得到 4 个类似的查询,每个查询都会删除特定范围 (10-50]、(50, 100] 等的 id)。
希望这会有所帮助。
【讨论】:
以上是关于带有内部连接和限制的mysql删除的主要内容,如果未能解决你的问题,请参考以下文章