2008-09-29 78 views
3

我有一個使用鄰接列表模型的「任務列表」數據庫,因此每個「任務」可以有無限的子任務。該表有一個'TaskOrder'列,所以在樹視圖中所有東西都以正確的順序呈現。SQL對層次中的節點進行重新排序

是否有SQL語句(MS-SQL 2005)將選擇指定父級的所有子節點並在刪除兄弟級別時更新TaskOder列?

 
Task Table 
---------- 
TaskId 
ParentTaskId 
TaskOrder 
TaskName 
--etc-- 

任何想法?謝謝。

回答

1

幾種不同的方式...由於TaskOrder的範圍是父母ID,收集它並不是很難。在SQL Server中,我把一個觸發上刪除遞減你刪除了所有的人「更高」不是一個,從而縮小差距(僞如下):

CREATE TRIGGER ON yourtable FOR DELETE 
AS 
    UPDATE Task 
    SET TaskOrder = TaskOrder - 1 
    WHERE ParentTaskId = deleted.ParentTaskId 
    AND TaskOrder > deleted.TaskOrder 

如果你不想觸發,您可以先在查詢中捕獲parentID和TaskOrder,然後刪除該行,然後執行相同的更新語句,但使用文本而不是觸發器。

或者,如果您希望儘量減少服務器往返次數,您可以將待刪除的任務一直移動到底部,然後移動其他任務,然後執行刪除操作,但看起來過於複雜。

2

如果您只使用TaskOrder進行排序,那麼只需簡單地在TaskOrder中留下空位,因爲只需刪除項目就不會使排序錯誤。但是,我不確定您的應用程序的需求。

0

不是直接。這是一個Topological Sort,您將子節點「懸掛」在父母身上。如果孩子中沒有依賴關係,他們執行的順序並不重要。如果孩子必須以某種順序執行,那麼你沒有足夠的信息來推斷這一點 - 他們將不得不有更多的層次。

假設父母中的孩子的順序是不相關的,那麼topoligical排序會讓你得到你想要的。你不會在大多數SQL方言中將這個問題變成一個單一的查詢 - 你將不得不寫一個sproc來做到這一點。

如果節點內的孩子的順序是相關的,那麼您需要維護父代中的任務順序。使用ParentNodeID,TaskOrder和count(*)的查詢將挑選出重複項,但除非系統有額外的信息來訂購任務,否則您仍然需要手動干預才能選擇正確的順序。

如果你想讓我澄清一些事情,請添加評論。

0

這看起來像是ROW_Number的作業。

DECLARE @Tasks TABLE 
(
    TaskId int PRIMARY KEY, 
    ParentTaskId int, 
    TaskOrder int, 
    TaskName varchar(30) 
) 

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName) 
SELECT 1, null, 1, 'ParentTask' 

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName) 
SELECT 2, 1, 2, 'B' 

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName) 
SELECT 3, 1, 1, 'A' 

INSERT INTO @Tasks(TaskId, ParentTaskId, TaskOrder, TaskName) 
SELECT 4, 1, 3, 'C' 
--Initial 
SELECT * FROM @Tasks WHERE ParentTaskId = 1 ORDER BY TaskOrder 

DELETE FROM @Tasks WHERE TaskId = 2 
--After Delete 
SELECT * FROM @Tasks WHERE ParentTaskId = 1 ORDER BY TaskOrder 


UPDATE t 
SET TaskOrder = NewTaskOrder 
FROM @Tasks t 
    JOIN 
(
SELECT TaskId, ROW_Number() OVER(ORDER BY TaskOrder) as NewTaskOrder 
FROM @Tasks 
WHERE ParentTaskId = 1 
) sub ON t.TaskId = sub.TaskId 

--After Update 
SELECT * FROM @Tasks WHERE ParentTaskId = 1 ORDER BY TaskOrder 
0

刪除任務88:

UPDATE TaskTable 
SET ParentTaskID = (SELECT ParentTaskID AS temp FROM Task_Table t1 WHERE TaskID = 88) 
WHERE 
TaskID IN (SELECT TaskID task2 FROM TaskTable t2 WHERE ParentTaskID = 88); 
Delete FROM TaskTable WHERE TaskID = 88; 

當然,你可以消除刪除,並且只留下躺在身邊以備將來報告目的的記錄。

CAVEAT:NOT TESTED !!!

相關問題