Сортировка по пустоте

VANHALEN

Новичок
Столкнулся с не совем обычным случаем. Имею скрипт меню
PHP:
function menu($group)	
	{
		$result = mysql_query("SELECT * FROM `menu` WHERE `group` = $group ORDER BY `position` ASC, `id` DESC");    
		while ($row = mysql_fetch_array($result)) 
			{
				$tree[] = array('name' => $row['menu'], 'id' => $row['id'], 'pid' => $row['pid'], 'page' => $row['page']);
			}
		function get_tree($tree, $pid)
			{
				$html = '';
				foreach ($tree as $row)
				{
					if ($row['pid'] == $pid)
					{
						$html .= '<li><a href="'.$row['page'].'">'.$row['name'].'</a>';
						$html .= '' . get_tree($tree, $row['id']);
						$html .= '</li>' . "\n";
					}
				}
				return $html ? '<ul>'.$html.'</ul>' . "\n" : '';
			}
		echo '<div id="menu">'.get_tree($tree, 0).'</div>';
	}
Хреновина в том что поле position по умолчанию вообще не заполнено. В админке, в управлении меню сдлано просто тупо перетягивание пункта меню при помощи jqwery. Как перетянешь, сразу записываются в массив все новые позиции и заносятся в базу. Когда похожая ситуация была у меня в фотоальбоме - это было круто. Что отсортировано, то отсортировано, а что добавилось и не трогалось (тоесть новые фотки) - появляется наверху. А вот как бы с меню нужда обратная. То, что добавилось позже, должно быть в конце меню.

Собственно надо спросить мускул так.. Сначала сортируется все пункты меню, где заполнено поле position, потом вниз добавляются все пункты в которых position пустое и они в свою очередь сортируются по id. Можно ли как нибудь не сильно меняя логику и не сильно извращаясь? Сейчас кстати второе условие в результате вообще лесом идёт.. Меняю направление сортировки в нём и ничего не происходит.
 

С.

Продвинутый новичок
А можно просто исполжовать default значение position такое, чтобы оно всегда оказывалось в конце.
 

VANHALEN

Новичок
или предусмотреть при добавлении пункта, чтобы ему присваивалось значение MAX(position)+1
Да, конечно можно. Лишний запрос в данном случае не смертелен. Единственное, что есть нюанс, из-за которого не уверен (я ещё не пробовал). Позиции уникальны только в пределах своего pid. На скрине видно. Хотя да, чем это может помешать..
можно использовать UNION
Копну в эту сторону, спасибо!

А вообще хотелось бы найти элегантное решение, без спрашивания какой position самый большой. Я и спросил то потому, что не вируоз в SQL запросах.
 

Вложения

HEm

Сетевой бобер
значение по умолчанию 66666 избавит от размышлений
 

WMix

герр M:)ller
Партнер клуба
Сначала сортируется все пункты меню, где заполнено поле position, потом вниз добавляются все пункты в которых position пустое
ORDER BY FIND_IN_SET( if(position is null ,'empty', 'not_empty') , 'not_empty, empty' )...
выделенное жирным нужно заменить на то как ты дефинируешь где НЕ заполнено поле position

зы кажись пробел лишний
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
необязательно быть экспертом, но сначала надо загуглить, ответ в 1м результате,
и тем более не советовать всякую фигню с магическими константами, подзапросами и юнионами

ORDER BY ISNULL(position), position, id DESC


Кстати, http://troels.arvin.dk/db/rdbms/ описан еще и недокументированный синтаксис mysql :)

ORDER BY -position DESC, position
 

С.

Продвинутый новичок
Если выбирать между правильным default значением и экзотическим выражением в ORDER BY, по-моему ни один адекватный человек не будет колебаться.
 

MiksIr

miksir@home:~$
И все потому, что mysql уже много лет не поддерживает NULLS FIRST/LAST с обещанием "когда-нибудь в будущем это сделать" =)
 

VANHALEN

Новичок
значение по умолчанию 66666 избавит от размышлений
Имхо не своем верный подход.. Как таковой, сортировки по id не будет, хотя пункт меню уберётся в зад. А если их создали 5, 10? В каком они порядке тогда между собой выстроются?
А вот остальные советы испробую обязательно.. Отпишусь, когда сделаю..

P.S. По поводу тормозов - ну сколько в меню не "мега портала" будет ответов при запросе? Принибрежительное колличество. Хотя подход правильный. И к тому же обратите внимание на поле "group". Это собственно и есть меню.. Одно сверху, другое снизу, слева, справа.. ТОесть много всяко не будет.
 

С.

Продвинутый новичок
Имхо не своем верный подход.. Как таковой, сортировки по id не будет, хотя пункт меню уберётся в зад. А если их создали 5, 10? В каком они порядке тогда между собой выстроются?
А если там был бы не 66666, а NULL, каком они порядке между собой выстроЮтся, у тебя вопроса не возникает?
 

VANHALEN

Новичок
ORDER BY ISNULL( position ) , position, id ASC
Ну вот почти, только надо наоборот. Как это наоборот звучать будет? Тоесть позиция не пустая.. а сейчас наоборот сначала выдаёт те, где "position" на заполнено
А если там был бы не 66666, а NULL, каком они порядке между собой выстроЮтся, у тебя вопроса не возникает?
Возникало. Подозреваю что именно по id, но только в другом (обратном) порядке.
 

Вложения

VANHALEN

Новичок
ORDER BY FIND_IN_SET( if(position is null ,'empty', 'not_empty') , 'not_empty, empty' )...
выделенное жирным нужно заменить на то как ты дефинируешь где НЕ заполнено поле position
Нихрена, если честно не понял.. Вертел и так и сяк. Выдаёт непонятный разнобой. Никогда не использовал выражения в запросах, собственно отууда и косяк. Я уж не знаю, можно ли нагло просить просто написать.. Ну если нет, буду сам ковырять, если да, пополню копилку знаний и попытаюсь разобраться

У меня была идейка даже отсортировать массив, но опять же знаний не хватило.. Массив сортировался только по (одному) первому ключу..
 

Semen

Семён
Ну вот почти, только надо наоборот. Как это наоборот звучать будет? Тоесть позиция не пустая.. а сейчас наоборот сначала выдаёт те, где "position" на заполнено
PHP:
ORDER BY ISNULL( position ) DESC, position , id ASC // сначала пустые
ORDER BY ISNULL( position ) ASC , position, id ASC //  сначала непустые
 

С.

Продвинутый новичок
Возникало. Подозреваю что именно по id, но только в другом (обратном) порядке.
То есть если у них у всех одинаково стоит NULL, то ты подозреваешь(!!!), что они отсортируются по id.
А если у них у всех одинаково будет 666666, то их id волшебным образом перепутаются.
Изумительная программистская логика!
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Если выбирать между правильным default значением и экзотическим выражением в ORDER BY, по-моему ни один адекватный человек не будет колебаться.
молодец, попал пальцем в небо :) от сути вопроса ушел в обсуждение логики приложения

критерий экзотичности сможешь дать? твои пробелы в знаниях - не подходит
противоречие стандарту ANSI SQL и отсутствие поддержки синтаксиса в других СУБД - тоже не подходит, иначе auto_increment тоже надо заменять на (условно) 6666666


Semen какой хороший человек! помоги ТСу еще - перечисли ему денег, чтобы ему не пришлось писать код вообще! :)
 
Сверху