2015-09-28 59 views
0

首先,我需要一个解决方案OracleMySQLMySql/Oracle删除数字列的空位

我有一个文件夹表:

 
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 

positionNOT NULLUNIQUE约束。

问题:
有时候,我不得不删除单个查询一些文件夹(如:删除文件夹 '一', '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 

任何想法?

感谢

+0

'删除间隙'是否意味着更新表? –

+0

是的,我需要更新表,但我在一个请求中搜索这样做 – Yoplaboom

+0

同样的SQL语句必须与MySQL和Oracle一起工作吗?可能会很棘手...... – jarlh

回答

0

我解决了这个问题:

甲骨文

 
    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 

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; 
+0

您也可以使用'(order by pk_id)' –

+0

不确定ON是否应该是'(t1.pk_id = sub.pk_id)'但我想你可以玩别名:) –

+0

我想你的解决方案,谢谢 – Yoplaboom