MySql/Oracle 删除数字列的间隙
MySql/Oracle Remove gaps of numeric column
首先,我需要 Oracle 和 MySQL.
的解决方案
我有一个文件夹 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 NULL
和 UNIQUE
约束。
问题:
有时我必须在单个查询中删除一些文件夹(例如:删除文件夹 '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
首先,我需要 Oracle 和 MySQL.
的解决方案我有一个文件夹 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 NULL
和 UNIQUE
约束。
问题:
有时我必须在单个查询中删除一些文件夹(例如:删除文件夹 '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