У меня есть такая таблица, которая представляет связанный список. Когда столбец comes_after
равен null
, это означает, что это первая запись в связанном списке.
id | comes_after
--------+------------
"one" | null
"two" | "one"
"three" | "two"
"four" | "three"
Как мне написать функцию, используя SQL или PLPG SQL для переупорядочения строк? Функция function move_id_after (id_to_move string, after_id string)
имеет 2 аргумента: id_to_move
- идентификатор для перемещения на новую позицию и after_id
- идентификатор для перемещения этой строки после. Если after_id
равно нулю, это значит переместить его в начало списка.
Это моя попытка, но она не работает, и это не кажется идеальным способом сделать это. Как показано в примерах, я хотел бы также иметь возможность перемещать строку в самое начало списка или в самый конец и обрабатывать случаи, когда ничего не нужно менять.
create function move_id_after (id_to_move string, after_id string) language plpgsql as $$
declare
AFTER_id_to_move string;
AFTER_after_id string;
id_to_move_used_to_follow string;
begin
select id from mytable where comes_after = id_to_move into AFTER_id_to_move;
select id from mytable where comes_after = after_id into AFTER_after_id;
update mytable set comes_after = id_to_move where id = AFTER_after_id;
update mytable set comes_after = AFTER_after_id where id = id_to_move returning id into id_to_move_used_to_follow;
update mytable set comes_after = id_to_move_used_to_follow where id = id_to_move_after;
end $$;
Вот примеры некоторых случаев того, каким должен быть результат.
Перемещение записи в другую позицию
select move_id_after("two", "three")
должно стать:
id | comes_after
--------+------------
"one" | null
"three" | "one"
"two" | "three"
"four" | "two"
Переместить запись в позицию, в которой он уже находится
select move_id_after("three", "two")
не должно быть никаких изменений:
id | comes_after
--------+------------
"one" | null
"two" | "one"
"three" | "two"
"four" | "three"
Переместить первую запись в последнюю позицию
select move_id_after("one", "four")
должно стать:
id | comes_after
--------+------------
"two" | null
"three" | "two"
"four" | "three"
"one" | "four"
Переместить последнюю запись в первую позицию
select move_id_after("four", null)
должно стать:
id | comes_after
--------+------------
"four" | null
"one" | "four"
"two" | "one"
"three" | "two"