Здравствуйте! есть база данных, примерно такая: Есть четыре запроса: Код (Text): UPDATE `item` SET `item_1` = `item_1` - 1 WHERE (`item_1` > 0) AND (`time`- $time >= 86400) UPDATE `item` SET `item_2` = `item_2` - 1 WHERE (`item_2` > 0) AND (`time`- $time >= 86400) UPDATE `item` SET `item_3` = `item_3` - 1 WHERE (`item_3` > 0) AND (`time`- $time >= 86400) UPDATE `item` SET `item_4` = `item_4` - 1 WHERE (`item_4` > 0) AND (`time`- $time >= 86400) Возможно ли их объединить в один запрос? Спасибо.
Объединить можно, но я не уверен, что такой запрос будет эффективней, чем четыре простых запроса. PHP: <?php $query = "UPDATE `tbl_name` SET `item_1` = `item_1` - (CASE WHEN `item_1` > 0 AND `time`- $time >= 0 THEN 1 ELSE 0 END), `item_2` = `item_2` - (CASE WHEN `item_2` > 0 AND `time`- $time >= 0 THEN 1 ELSE 0 END), `item_3` = `item_3` - (CASE WHEN `item_3` > 0 AND `time`- $time >= 0 THEN 1 ELSE 0 END), `item_4` = `item_4` - (CASE WHEN `item_4` > 0 AND `time`- $time >= 0 THEN 1 ELSE 0 END)";
А как по-другому? В этих колонках разные данные и объединить их в одну не получится. Задача примерно такая: есть контейнер в котором 4 отделения. Если в одном отделении что-то лежит, то другие должны быть пусты. То-есть если Item_1 больше 0, то остальные item'ы будут равны 0. Но раз в сутки скрипт должен отнять единицу от Item'а, который больше 0.
на вид там число. т.е. данные одинаковые. значит получится. =) --- Добавлено --- с правильной формулировки задачи начинается правильное решение. Хз какое оно, надо подумать. Но с формулировки "помогите смазать костыли" правильное решение не начинается. Навскидку могу предложить два поля - номер ящика и сколько в нём лежит.
Согласен =) Просто когда знаешь что тебе нужно, кажется что и другим это тоже понятно. Попытаюсь объяснить все еще раз: PHP: <?php //есть массив данных $item_arr = array('item_1' => 5, 'item_2' => 0, 'item_3' => 0, 'item_4' => 0, 'time' = 100000); //только один из 4-х итемов больше 0, остальные равны 0. //на всякий случай проверяем if ($item_arr['item_1'] > 0) { $item_1 = $item_arr['item_1']; $item_2 = 0; $item_3 = 0; $item_4 = 0; } else if ($item_arr['item_2'] > 0) { $item_1 = 0; $item_2 = $item_arr['item_2']; $item_3 = 0; $item_4 = 0; } else if ($item_arr['item_3'] > 0) { $item_1 = 0; $item_2 = 0; $item_3 = $item_arr['item_3']; $item_4 = 0; } else if ($item_arr['item_4'] > 0) { $item_1 = 0; $item_2 = 0; $item_3 = 0; $item_4 = $item_arr['item_4'];; } //далее записываем в базу данных mysqli_query($link, "INSERT INTO `items` (`item_1`, `item_2`, `item_3`, `item_4`, `time`) VALUES ('$item_1','$item_2','$item_3','$item_4','$item_arr['time'])"); ?> Вот, а раз в сутки мне нужно уменьшить те ячейки, которые больше 0 на единицу. Вопрос в том, можно ли это сделать одним запросом, или нужно делать четыре запроса. То есть по одному запросу для каждого поля item?
ИМХО так лучше: PHP: <?php //есть массив данных $item_arr = array(5, 0, 0, 0); $time = 100000; $new_arr = null; //только один из 4-х итемов больше 0, остальные равны 0. //на всякий случай проверяем foreach($item_arr as $k=>$v){ if($item_arr[$k] > 0){ $new_arr = [0,0,0,0]; $new_arr[$k] = $v; break; } } if(is_null($new_arr)){ // этой проверки в вашем коде небыло! т.е. если во всех ячейках числа <= 0. } //далее записываем в базу данных $sql = []; foreach($new_arr as $k=>$v) $sql[] = "(1, {$k+1}, $v, $time)";// $k+1 ради того чтобы был отсчет от 1, как у вас. // Хотя, обычно у программистов отсчет от 0 всегда. mysqli_query($link, "INSERT INTO `items` (`row`, `cell`, `value`, `time`) VALUES ".implode(', ',$sql)); // РАЗ В СУТКИ $today = mktime(0,0,0); // это таймштамп начала текущих суток mysqli_query($link, "UPDATE `tbl_name` SET `value` = `value`-1 AND `time` = UNIX_TIMESTAMP()" ." WHERE `time` < ".$today." AND `value` > 0"); // такой подход к датам позволит ликвидировать опастность двойной обработки данных в пределах одних суток.
потому что если будут два поля - номер ящика и счётчик, то можно будет снижать счётчик у всей таблицы одним запросом не зависимо от того, в каком ящике что лежит.
Да. Но будет удобнее. А какая разница? БД создана ради того, чтобы работать с большим количеством строк. И она будет работать быстро, если ею правильно пользоваться. Такой вариант (когда строк больше) оптимальный, потому что будут быстро выполнятся запросы на выборку и обновление одинаково эффективно. В вашем же варианте 4 запроса на обновление вместо одного. Даже со всякими хитростями типа CASE все равно это получается костыль, а не нормальная и быстрая работа БД. Конечно, не забудьте добавить индексы.
я не вижу почему строк будет больше, если может быть занят только один ящик из четырёх. Так же одна строка на четыре ящика с полями номер ящика и сколько лежит.
Я понял. Вы говорите о том, что в базу будет записывать только тот ящик, в котором что-то лежит, а пустые ящики записываться не будут?
да. номер ящика и сколько лежит. --- Добавлено --- это позволяет одним запросом прогонять декремент по времени по всем записям в базе. и никаких дополнительных условий.