假设我们在一个表中有记录,我们希望能够对它们进行排序(并重新排序)。
这张table可能看起来像这样,见下图
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是唯一的id(可以是任何东西), position
元素在列表中的位置, level
深度级别和 parentId
父id(如果存在)
通常我需要以下方法:
/**
@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]
实现这一点最有效的方法是什么?还是我遗漏了什么?在(我的)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
1条答案
按热度按时间7rtdyuoh1#
为了构造树结构,我将使用递归cte,如下所示。把它构造成一个视图
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=334820e4e01cf8749c5aa447963a0