есть некая таблица `table`, в ней всего 3 поля `user_id` и `order` (являющие собой составной уникальный ключ) и некое `somth`.
Допустим она содержит следующие записи (значения `user_id` - `order` - `somth`):
123 - 0 - 'somth_123_0'
123 - 1 - 'somth_123_1'
123 - 2 - 'somth_123_2'
123 - 3 - 'somth_123_3'
123 - 4 - 'somth_123_4'
123 - 5 - 'somth_123_5'
124 - 0 - 'somth_124_0'
124 - 1 - 'somth_124_1'
124 - 2 - 'somth_124_1'
я считываю все записи об `user_id` = 123, сортирую по `order`, и загоняю в массив следующим образом:
$q = mysql_query("select * from `table` where user_id = 123 order by `order`");
//$count = 0;
$data = array();
while($f = mysql_fetch_assoc($q))
{
//$count++;
$data[$f['order']] = $f['user_id'];
}
тоесть, `order` становится ключем массива.
далее, по какимто причинам из массива удаляются N элементов, пускай, для примера, N = 2, а элементы будут соответствовать ключам 1 и 4, после чего масиив стал таким:
array(
0 => 123,
//unseted
2 => 123,
3 => 123,
//unsetted
5 => 123,
);
из таблицы эти записи тоже были удалены, она стала такой:
123 - 0 - 'somth_123_0'
//deleted
123 - 2 - 'somth_123_2'
123 - 3 - 'somth_123_3'
//deleted
123 - 5 - 'somth_123_5'
124 - 0 - 'somth_124_0'
124 - 1 - 'somth_124_1'
124 - 2 - 'somth_124_1'
=============================
ЗАДАЧА:
ОДНИМ запросом, не вешая дополнительных полей в таблицу, изменить значения `order`, оставшихся в таблице для user_id = 123, так, что бы они снова были упорядочены от 0 до (count($data) - N - 1) c сохранением фактического порядка.
тоесть, что бы в результате запроса табллица стала такой:
123 - 0 - 'somth_123_0'
123 - 1 - 'somth_123_2'
123 - 2 - 'somth_123_3'
123 - 3 - 'somth_123_5'
124 - 0 - 'somth_124_0'
124 - 1 - 'somth_124_1'
124 - 2 - 'somth_124_1'
=============================
Как это пытался сделать я:
первое что пришло на ум, это UPDATE c CASE..END
както так:
$new_order = 0;
$upd_orders = array();
$upd_orders_case = '';
foreach($data AS $old_order => $null)
{
if($old_order != $new_order)
{
$upd_orders[] = $old_order;
$upd_orders_case .= "WHEN $old_order THEN $new_order";
}
$new_order++;
}
mysql_query("update `table` SET `order` = CASE $upd_orders_case END WHERE user_id = 123 AND `order` IN (".implode(',', $upd_orders).")");
логично вроде бы. НО. тогда ордеры будут перезатираться, чего нам не нужно. кроме того в нашем случае возможны ошибки так как ключ юзер-ордер уникален.
вроде бы не беда, просто добавляем в запрос
mysql_query("update `table` SET `order` = CASE $upd_orders_case END WHERE user_id = 123 AND `order` IN (".implode(',', $upd_orders).") ORDER BY `order`");
но вот не задача! ORDER BY почемуто у меня отказывается работать совместно с IN. Перезатирает таки..
Почему? Как исправить? как решить поставленную задачу? есть мысли?
"далее, по какимто причинам из массива удаляются N элементов"
ну так в примере в поле order не уникальные значения.
Ну блин, я же написал, что значения в поле ордер не уникальные и вот здесь
$data[$f['order']] = $f
['user_id']
перезаписываются ключи.
Fuelen, "`user_id` и `order` (являющие собой составной уникальный ключ)"
покажи в каком месте они не уникальны?
добавлено спустя 43 секунды:
Fuelen, $data[$f['order']] = $f
['user_id'] ничего тут не затирается
$q = mysql_query("select * from table where user_id = 123 order by `order`");
$count = 0;
$data = array();
while($f = mysql_fetch_assoc($q))
{
$count++;
$data[$count] = $f['user_id'];
}
====================
Надеюсь я тя правильно понял.
EmptyZero, нет.
именно так как есть.
"`order` становится ключем массива."
$count был введен только для того что бы составить эту фразу:
", что бы они снова были упорядочены от 0 до ($count - N - 1) c сохранением фактического порядка."
впрочем она не верна, исправил на
"
, что бы они снова были упорядочены от 0 до (count($data) - N - 1) c сохранением фактического порядка.
"
Тогда, значения элементов массива с одинаковыми ключами(у тебя они произвольные - `order`, а не упорядоченые) будут перезаписыватся
15 Сен 2012, 12:46 123 - 0 - 'somth_123_0'
123 - 1 - 'somth_123_1'
123 - 2 - 'somth_123_2'
123 - 3 - 'somth_123_3'
123 - 4 - 'somth_123_4'
123 - 5 - 'somth_123_5'
124 - 0 - 'somth_124_0'
124 - 1 - 'somth_124_1'
124 - 2 - 'somth_124_1'
тут как минимум несколько элементов с одинаковым order, а в массиве который ты создаешь, не может быть несколько одинаковых элементов (только 1 с уникальным значением, если будет еще один такой же - он будет перезаписан).
добавлено спустя 2 минуты:
вот тебе пример:
[php:1:3475a3e35c]
<?php
$array[0] = 'Test #0';
$array[1] = 'Test #1';
$array[0] = 'Test #0_2';
$array[1] = 'Test #1_2';
$array[2] = 'Test #2';
print_r($array);
?>
Array
(
[0] => Test #0_2
[1] => Test #1_2
[2] => Test #2
)
[/php:1:3475a3e35c]
добавлено спустя 5 минут:
а вообще для начала проверь тип поля order - INT
добавлено спустя 2 минуты:
[php:1:3475a3e35c]
<?php
$start = 0;
$end = (count($data)- N - 1);
$users = mysql_query("SELECT `somth` FROM `table` WHERE `user_id` = '123'");
while($user = mysql_fetch_assoc($users);
{
if($start <= $end)
{
mysql_query("UPDATE `table` SET `order` = '".$start."' WHERE `somth` = '".$user['somth']."'");
}
$start++;
}
?>[/php:1:3475a3e35c]
добавлено спустя 49 секунд:
^ решение первого поста
Цитата:
"
ОДНИМ запросом, не вешая дополнительных полей в таблицу, изменить значения `order`, оставшихся в таблице для user_id = 123, так, что бы они снова были упорядочены от 0 до (count($data) - N - 1) c сохранением фактического порядка.
"
добавлено спустя 1 минуту:
в общем ход действий такой:
1) разберись с одинаковыми ключами массива
2) проверь тип поля (иначе ORDER BY будет работать неверно!
3) используй последний php код моего поста. если я правильно тебя понял, так и должно быть.