2015-02-05 5 views
1

Это единственный способ, которым я мог бы это сделать, и я получаю сообщение об ошибке. Я пытаюсь удалить в кусках внутри цикла while, поскольку итоговое значение может быть довольно большим.mysql delete with internal joins and limit

Первое утверждение счетчика отлично работает. Это второй оператор 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

При наличии нескольких таблиц в запросе удаления вам необходимо сообщить БД, из которой следует удалить таблицы. Вы можете сделать это в первой строке

DELETE app_logs 
FROM app_logs 
INNER JOIN users ON ... 
INNER JOIN computers ON ... 
0

Как mentioned in the docs, а также in this answer, LIMIT не могут быть использованы вместе DELETE + JOIN.

Если вам нужно как-то ограничить удаление, просто создайте условия для оператора DELETE, который будет эмулировать ваш раздел LIMIT. Например, вы можете выполнить следующие действия:

  1. принять минимум и идентификаторы максимума строк из запроса, который нужно удалить значения из (позволяет сказать: 10 и 200)
  2. Затем выберите граничащие иды имитируя лимит (так что для предела 50, приграничные идентификаторы могут быть 50, 100, 150, 200)
  3. Затем для каждого граничащего ID, запрашивать DELETE заявления с WHERE имея AND id <= ?, и поместить каждую граничащего идентификатор в месте от ?.
  4. Таким образом, вы в конечный итоге с 4 подобными запросами, каждый из них удаление идентификаторов из определенного диапазона (10-50], (50, 100] и т.д ..

Надеется, что это помогает.