Comments 10
Можно кодировать позицию дробным числом в интервале (0; 1). Таких чисел континуум, так что вам точно хватит. Заодно пропадает необходимость пересчитывать позиции вообще.
нет. это большая нагрузка на систему хранения. Так то можно и бесконечную строку для хранения позиции использовать. При перемещении надо сравнивать еще позицию после, чтобы корректно позицию посчитать. Сложно.
Есть красивый простой алгоритм для этой задачи, но до него надо дойти.
это большая нагрузка на систему хранения
Серьёзно? Вы уже храните дробные позиции, такие, как 2,5 из примера.
Чтобы поменять... два и три... нужно второму элементу задать позицию с номером, БОЛЬШИМ чем три.
Имеем очередную задачку, когда "кто-то что-то имел ввиду", но не смог корректно сформулировать условие. Не удивительно, что коллеги не справились.
Читайте последний пример с тремя группами. Там написано буквально "для военных", если вам в этом примере что-то не понятно, готов пояснить. но мне кажется, там идеально просто. И если вы решите этот пример, то как раз его и хватит для насладжения изяществом решения задачи.
Или вы включили "буквоеда"?
Так, задачу уже все же решили коллеги на Мисте. Рекомендую попробовать решить самостоятельно.
Я бы предложил "сортировку подсчетом": посчитать число элементов того же родителя с меньшим значением "числа упорядочивания" и добавить единицу. Это если я правильно понял задачу - здесь именно это самое сложное.
В описании получается, что каждый набор детей в рамках единого родителя независим, то есть он совершенно отдельно от остальных наборов проверяется и (пере)нумеруется. Никакие изменения - ни ручные, ни пересчёт в пределах одного родителя в принципе не влияют на валидность нумерации детей другого родителя.
Соответственно при внесении изменений в нумерацию детей некоего родителя пересчёту следует подвергать только список детей этого родителя. При проверке - рекурсивно обходить всё дерево иерархии, и для каждого узла, имеющего подчинённые, проверять и/или пересчитывать их нумерацию.
Эффективный обход узлов, имеющих подчинённые узлы - стандартная задача на рекурсивный CTE.
Эффективная проверка и при необходимости перенумерация детей одного родителя - это, несомненно, применение ROW_NUMBER(). Реализация сильно СУБД-зависима, но опять же никаких проблем не вижу, всё просто и плоско (надеюсь, первичный ключ в таблице таки присутствует).
Так что в упор не понимаю, чего в этой задаче такого особенного...
Гуру тест про порядок элементов в иерархии