Xwab
Форумыnavigate_nextПрограммирование на PHP

Вроде простой, но не совсем запрос
Сообщения
M0rtiis

есть некая таблица `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. Перезатирает таки..

Почему? Как исправить? как решить поставленную задачу? есть мысли?


__________
посл.ред. 15 Сен 2012, 3:10; всего 2 раз(а) 12 Сен 2012, 1:35
Fuelen

"далее, по какимто причинам из массива удаляются N элементов"
ну так в примере в поле order не уникальные значения.

12 Сен 2012, 19:25
M0rtiis

как же так то? ксерг, акдмех, морган, сан, геморой, где вы все?

13 Сен 2012, 0:51
Fuelen

Ну блин, я же написал, что значения в поле ордер не уникальные и вот здесь
$data[$f['order']] = $f
['user_id']
перезаписываются ключи.

14 Сен 2012, 13:12
M0rtiis

Fuelen, "`user_id` и `order` (являющие собой составной уникальный ключ)"

покажи в каком месте они не уникальны?
добавлено спустя 43 секунды:
Fuelen, $data[$f['order']] = $f
['user_id'] ничего тут не затирается

14 Сен 2012, 19:21
EmptyZero

$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'];
}
====================
Надеюсь я тя правильно понял.

14 Сен 2012, 23:48
M0rtiis

EmptyZero, нет.
именно так как есть.

"`order` становится ключем массива."

$count был введен только для того что бы составить эту фразу:

", что бы они снова были упорядочены от 0 до ($count - N - 1) c сохранением фактического порядка."

впрочем она не верна, исправил на
"
, что бы они снова были упорядочены от 0 до (count($data) - N - 1) c сохранением фактического порядка.
"

15 Сен 2012, 3:10
EmptyZero

Тогда, значения элементов массива с одинаковыми ключами(у тебя они произвольные - `order`, а не упорядоченые) будут перезаписыватся

15 Сен 2012, 12:46
M0rtiis

EmptyZero, где??? они и уникальные и упорядоченные

15 Сен 2012, 22:28
Default_mo

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 код моего поста. если я правильно тебя понял, так и должно быть.

15 Сен 2012, 23:04
Ответить на тему