2015-09-28 31 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