LINUX.ORG.RU

[php][mysql]Расположить строки в нужном порядке

 ,


0

1

Есть сайт на PHP+MySQL, есть таблица, скажем, со столбцами id и content и с несколькими строками. Это могут быть правила, которые должны выполняться в определённом порядке, или упорядоченные разделы форума.

В таблице строки расположены в порядке добавления, типа:
1 contA
2 contB
3 contC

Теперь я хочу их расположить в нужном мне порядке, например, так:
contB
contA
contC

Можно перебить им индексы.
Можно добавить float-поле, в нём пронумеровать строки, а в случае добавления между двумя строками ещё одной давать ей номер 1,5, 1,75 и т.д.
Можно нумерацию вывести прямо в интерфейс, пусть пользователь руками вписывает приоритеты.
Но такие решения мне не кажутся красивыми и изящными. Тем более порядок может изменяться весьма часто.

Если кто-то знает, как решаются такие задачи — поделитесь.

★★★★★

> Можно перебить им индексы

Для смены порядка следования строк в таблице меняйте соответствующие им индексы местами:

1 contA
2 contB
3 contC

====>

*2* contA
*1* contB
3 contC

Для этого используем SQL оператор UPDATE.
Возможно, удобнее и проще завести отдельный, независимый от id, столбец для обозначения порядка c использованием типа UNSIGNED INT.
Назовем этот столбец `rank`.

в случае добавления между двумя строками ещё одной...


Значение поля `rank` для всех последующих строк увеличиваем на 1.

Пример:

id rank content
-----------------
1 1 contA
2 2 contB Добавим новую строку сразу после этой
3 3 contC
4 4 contD

===>

id rank content
-----------------
1 1 contA
2 2 contB

*5* *3* contE

3 4 contC (rank = 3+1)
4 5 contD (rank = 4+1)

Можно нумерацию вывести прямо в интерфейс, пусть пользователь руками вписывает приоритеты. ...порядок может изменяться весьма часто


Но такие решения мне не кажутся красивыми и изящными.

Согласен.

Deleted
()

Вот кусок кода, который реализует нечто подобное, по алгоритму, схожему с описаным выше. вдруг чемто поможет.

// Перемещение записи
if ($_GET['type'] == "mv") {
	$id = substr($_GET['id'], 3);
	$before_type = substr($_GET['before'], 0, 2);
	$before_id = substr($_GET['before'], 3);
	if ($before_type == "mi") { // Размещение пункта под любым другим, кроме последней записи в каждом элементе
		$res_moved = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `id`='" . $id . "';");
		$res_before = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `id`='" . $before_id . "';");
		if ($res_moved[0]['pid'] == $res_before[0]['pid']) { // Перемещение в пределах одного родительского элемента
			if ($res_moved[0]['zindex'] < $res_before[0]['zindex']) { // Перемещение с увеличением zid (Вниз)
				$res_ch = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `pid`='" . $res_moved[0]['pid'] . "' AND `zindex`>'" . $res_moved[0]['zindex'] . "' AND `zindex`<'" . $res_before[0]['zindex'] . "' ORDER BY `zindex` DESC;");
				if (count($res_ch) > 0) {
					$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . $res_ch[0]['zindex'] . "' WHERE `id`='" . $res_moved[0]['id'] . "';");
					for ($i = 0; $i < count($res_ch); $i++) {
						$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . ($res_ch[$i]['zindex'] - 1) . "' WHERE `id`='" . $res_ch[$i]['id'] . "';");
					}
				}
			} else { // Перемещение с уменьшением zid (Вверх)
				$res_ch = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `pid`='" . $res_moved[0]['pid'] . "' AND `zindex`<'" . $res_moved[0]['zindex'] . "' AND `zindex`>='" . $res_before[0]['zindex'] . "' ORDER BY `zindex` ASC;");
				if (count($res_ch) > 0) {
					$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . $res_ch[0]['zindex'] . "' WHERE `id`='" . $res_moved[0]['id'] . "';");
					for ($i = 0; $i < count($res_ch); $i++) {
						$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . ($res_ch[$i]['zindex'] + 1) . "' WHERE `id`='" . $res_ch[$i]['id'] . "';");
					}
				}
			}
		} else { // Перемещение из одного родительского элемента в другой
			$res_ch = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `pid`='" . $res_before[0]['pid'] . "' AND `zindex`>='" . $res_before[0]['zindex'] . "' ORDER BY `zindex` ASC;");
			for ($i = 0; $i < count($res_ch); $i++) {
				$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . ($res_ch[$i]['zindex'] + 1) . "' WHERE `id`='" . $res_ch[$i]['id'] . "';");
			}
			$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . $res_ch[0]['zindex'] . "', `pid`='" . $res_before[0]['pid'] . "' WHERE `id`='" . $res_moved[0]['id'] . "';");
			$res_ch = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `pid`='" . $res_moved[0]['pid'] . "' AND `zindex`>'" . $res_moved[0]['zindex'] . "' ORDER BY `zindex` ASC;");
			for ($i = 0; $i < count($res_ch); $i++) {
				$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . ($res_ch[$i]['zindex'] - 1) . "' WHERE `id`='" . $res_ch[$i]['id'] . "';");
			}
		}
	} else { // Размещение перед последней записью элемента
		$res_moved = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `id`='" . $id . "';");
		$res_ch = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `pid`='" . $res_moved[0]['pid'] . "' AND `zindex`>'" . $res_moved[0]['zindex'] . "' ORDER BY `zindex` ASC;");
		for ($i = 0; $i < count($res_ch); $i++) {
			$db -> query("UPDATE `" . PN . "tree` SET `zindex`='" . ($res_ch[$i]['zindex'] - 1) . "' WHERE `id`='" . $res_ch[$i]['id'] . "';");
		}
		$res_to = $db -> query("SELECT * FROM `" . PN . "tree` WHERE `pid`='" . $before_id . "';");
		$zindex = count($res_to);
		$db -> query("UPDATE `" . PN . "tree` SET `pid`='" . $before_id . "', `zindex`='" . $zindex . "' WHERE `id`='" . $res_moved[0]['id'] . "';");
	}
}
pilotys
()

Такие штуки делаются с помощью колонки sort, а удобство для юзера обеспечивается через DHTML+Ajax, где хватаешь мышкой нужную строку и передвигаешь вверх-вниз, а при отпускании кнопки Ajax-запрос на сервер, соответственно, апдейтит содержимое колонки. Во вконтактике так фотоальбомы сортируются - можешь посмотреть на примере.

karbofos
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.