MySql / Oracle删除数字列的间隙

时间:2015-09-28 07:43:04

标签: mysql sql oracle gaps-in-data

首先,我需要 Oracle MySQL 的解决方案。

我有一个文件夹表:

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

所以我需要在单个请求中更新表以更新位置列并按特定顺序(以防止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

任何想法?

由于

2 个答案:

答案 0 :(得分:1)

试试这个

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;

答案 1 :(得分:0)

我解决了这个问题:

的Oracle

    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