скажем, у нас есть записи в таблице, и мы хотели бы иметь возможность упорядочить (и изменить их порядок).
таблица может выглядеть примерно так, см. ниже
id Pos Level parentId
Europe 18 1 0 null
Germany 9 2 1 18
Berlin 2 3 2 9
Frankfurt 20 4 2 9
Stuttgart 23 5 2 9
France 29 6 1 18
Paris 26 7 2 29
Lyon 13 8 2 29
Americas 11 9 0 null
USA 27 10 1 11
New York 22 11 2 27
Manhattan 19 12 3 22
Brooklyn 7 13 3 22
Los Angeles 25 14 2 27
Mexico 6 15 1 11
Canada 4 16 1 11
Montreal 21 17 2 4
Vancouver 3 18 2 4
Asia 8 19 0 null
China 14 20 1 8
Beijing 17 21 2 14
Shenzhen 30 22 2 14
Shanghai 28 23 2 14
Japan 16 24 1 8
Tokyo 1 25 2 16
Shinjuku 15 26 3 1
Oceania 24 27 0 null
Autralia 5 28 1 24
Sydney 10 29 2 5
Africa
12 30 0 null
где id - это уникальный идентификатор (может быть любым), position
позиции элемента в списке, level
глубины уровня и родительский идентификатор parentId
(если существует)
Обычно я хотел бы следующий метод:
/**
@param sourceId: id of the element to be moved
@params targetId: id of the element which position needs to be overtaken
@param aboveOrBelow: defines whether the old element (target) will be placed above or below the source element
@return if successful, new position of the source element, if unsuccessful: message explaining why unsuccessful
*/
def move(sourceId: Long, targetId: Long, aboveOrBelow: Boolean = true):Either[Long, String]
какой самый эффективный способ реализовать это или я что-то упустил? Есть ли уже встроенный механизм для таких операций в (My) SQL?
ограничения: - конечный пользователь, которому может быть разрешено изменить порядок, не обязательно видит все записи (например, только asian
записи) - записи могут быть добавлены и удалены
=== изменить === я переписал структуру с учетом предложений в комментариях:
id pos parentId
Europe 18 1 null
Germany 9 1 18
Berlin 2 1 9
Frankfurt 20 2 9
Stuttgart 23 3 9
France 29 2 18
Paris 26 1 29
Lyon 13 2 29
Americas 11 2 null
USA 27 1 11
New York 22 1 27
Manhattan 19 1 22
Brooklyn 7 2 22
Los Angeles 25 2 27
Mexico 6 3 11
Canada 4 4 11
Montreal 21 1 4
Vancouver 3 2 4
Asia 8 3 null
China 14 1 8
Beijing 17 1 14
Shenzhen 30 2 14
Shanghai 28 3 14
Japan 16 2 8
Tokyo 1 1 16
Shinjuku 15 1 1
Oceania 24 4 null
Autralia 5 1 24
Sydney 10 1 5
Africa 12 5 null
А для построения древовидной структуры я бы использовал рекурсивный cte следующим образом. и построить его как вид
with recursive cte(place_name,id,parent_id,level)
as (select place_name,id,parent_id,1 as level
from countries_hierarchy
where parent_id is null
union all
select concat(lpad(' ',a.level+1,' ')
,b.place_name
)
,b.id
,b.parent_id
,a.level+1
from cte a
join countries_hierarchy b
on a.id=b.parent_id
)
select * from cte
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=334820e4e01cf8749c5abcaa447963a0