$sql = "SELECT `count1`, `count2`, `count3`
FROM `list`
WHERE `id` = ?";
foreach($data as $id =>$value ) {
$count=$value['count'];
$id=explode("-", $id);
$stmt = $conn -> prepare ($sql);
$stmt -> execute([$id[0]]);
$result = $stmt -> fetch(PDO::FETCH_ASSOC);
if ($id[1]== '1') {$result=(int)$result['count1']-$count; $column = 'count1';};
if ($id[1]== '2') {$result=(int)$result['count2']-$count; $column = 'count2';};
if ($id[1]== '3') {$result=(int)$result['count3']-$count; $column = 'count3';};
$sql_upd = "UPDATE `list`
SET $column = ?
WHERE `id` = ?";
$stmt = $conn -> prepare ($sql_upd);
$stmt -> execute ([$result,$id[0]]);
}
<?php
// Т.к. мы подставляем переменную $column прямо в SQL код без обработки,
// то мы обязаны позаботиться о том, чтобы там не было SQL-иньекций
// Поэтому, мы должны крайне тщательно проверить, соответствует ли наше значение допутимым вариантам
// Проверяем, что там только 1, 2 или 3, а также проверяем, чтобы там не было вредоносного "продолжения"
$columnNumber = (int) $id[1];
if ($columnNumber < 1 || $columnNumber > 3 || strlen($id[1]) > 1) {
throw new \InvalidArgumentException("Неверный номер поля");
}
$column = 'count' . $columnNumber; $column = 'count' . (int)$columnNumber;const COLUMNS = [
1 => 'column1',
2 => 'column2',
3 => 'column3',
];
if (!isset(COLUMNS[$id])) {
throw new \InvalidColumnException();
}
$column = COLUMNS[$id];
нормализация - это серебряная пуля и панацея. Один из ключевых принципов архитектуры.
И не надо ставить денормализацию на одну доску с ней. Это не принцип проектирования баз данных, а компромисс, который никогда не закладывается исходно, а добавляется сильно позже, когда (если) возникают проблемы с производительностью.
Чем схема плоха, я наглядно показал в своем ответе - при нормальной схеме - когда номер счетчика уходит в условие, где он и должен быть - сразу пропадает ВЕСЬ этот говнокод, и делается простой запрос апдейт.
UPDATE link_count SET count=count+? WHERE link_id=? and number=?
$sql = "UPDATE `list`
SET count1 = CASE WHEN id = ? AND ? = 1 THEN count1 - ? ELSE count1 END,
count2 = CASE WHEN id = ? AND ? = 2 THEN count2 - ? ELSE count2 END,
count3 = CASE WHEN id = ? AND ? = 3 THEN count3 - ? ELSE count3 END
WHERE id = ?";
$stmt = $conn->prepare($sql);
foreach ($data as $id => $value) {
$idParts = explode("-", $id);
$count = $value['count'];
$stmt->execute([$idParts[0], $idParts[1], $count, $idParts[0], $idParts[1], $count, $idParts[0], $idParts[1], $count, $idParts[0]]);
}
UPDATE `list`
SET count1 = CASE WHEN id = ? AND ? = 1 THEN count1 - ? ELSE count1 END,
count2 = CASE WHEN id = ? AND ? = 2 THEN count2 - ? ELSE count2 END,
count3 = CASE WHEN id = ? AND ? = 3 THEN count3 - ? ELSE count3 END
WHERE id = ?UPDATE `list`
SET count1 = CASE WHEN id = :id_part1 AND :id_part2 = 1 THEN count1 - :count ELSE count1 END,
count2 = CASE WHEN id = :id_part1 AND :id_part2 = 2 THEN count2 - :count ELSE count2 END,
count3 = CASE WHEN id = :id_part1 AND :id_part2 = 3 THEN count3 - :count ELSE count3 END
WHERE id = :id_part1const COLUMNS = [
1 => 'column1',
2 => 'column2',
3 => 'column3',
];
$column = COLUMNS[$id[1]];UPDATE `list` SET $column = $column - :count WHERE `id` = :id_part1
$column = COLUMNS[$id] ?? throw new InvalidColumnException();