MySql/Oracle 删除数字列的间隙

MySql/Oracle Remove gaps of numeric column

首先,我需要 OracleMySQL.

的解决方案

我有一个文件夹 table :

id | name | parent_id | position
_________________________________
1  | root | null      | 1
2  | a    | 1         | 1
3  | b    | 1         | 2
4  | b1   | 3         | 1
5  | b2   | 3         | 2
6  | c    | 1         | 3
7  | d    | 1         | 4
8  | e    | 1         | 5

给定树:

root
  |_ a
  |_ b
  |  |_b1
  |  |_b2
  |_c
  |_d
  |_e

position 具有 NOT NULLUNIQUE 约束。

问题:
有时我必须在单个查询中删除一些文件夹(例如:删除文件夹 'a'、'b1'、'd')。这样做时,我的文件夹位置有空隙:

id | name | parent_id | position
_________________________________
1  | root | null      | 1
3  | b    | 1         | 2
5  | b2   | 3         | 2
6  | c    | 1         | 3
8  | e    | 1         | 5

所以我需要在单个请求中更新 table 以更新位置列并按特定顺序(以防止 UNIQUE 约束)以获得结果:

id | name | parent_id | position
_________________________________
1  | root | null      | 1
3  | b    | 1         | 2
5  | b2   | 3         | 1
6  | c    | 1         | 2
8  | e    | 1         | 3

有什么想法吗?

谢谢

试试这个

MERGE
INTO    YourTable t1
USING   (
        SELECT pk_id, gap_ID, row_num() over (order by gap_id) as newGap
        FROM YourTable t2
        ) as sub
ON      (t1.pk_id = t2.pk_id)
WHEN MATCHED THEN
UPDATE
SET     gap_ID = newGap;

我解决了这个问题:

甲骨文

    UPDATE folders t 
    SET position = ( select count(*)
    FROM folders f1 INNER JOIN folders f2 on ( f1.parent_id = f2.parent_id   and f1.position >= f2.position )
    WHERE f1.id = t.id AND t.parent_id = f1.parent_id
    GROUP BY f1.id, f1.position );

MySQL

    UPDATE folders f
    INNER JOIN ( select f1.id, f1.parent_id, count(*) as newPos
    FROM folders f1 INNER JOIN folders f2 on ( f1.parent_id = f2.parent_id and f1.position >= f2.position)
    GROUP BY f1.parent_id, f1.position) t on ( t.id = f.id and t.parent_id = f.parent_id)
    SET f.position = t.newPos