2008-09-29 15 views
3

各「タスク」には無制限のサブタスクを持たせることができるように、隣接リストモデルを使用する「タスクリスト」データベースがあります。テーブルには 'TaskOrder'カラムがあり、すべてがツリービュー上で正しい順序でレンダリングされます。階層内のノードを並べ替えるためのSQL

兄弟が削除されたときに、指定した親のすべての子ノードを選択し、TaskOder列を更新するSQL文(MS-SQL 2005)がありますか?

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

ありがとう。

答えて

1

いくつかの異なる方法... TaskOrderは親IDでスコープされているので、それを集めることは非常に困難ではありません。

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

あなたはトリガーをしたくない場合は、次のSQL Serverでは、私は、それによって(擬似コードは以下の)ギャップを埋める、あなたが削除されたすべてのものを「高い」より1を減算すること、ON DELETEトリガをかけたいです最初にクエリのparentIDとTaskOrderを取得し、その行を削除してから同じ更新文を実行することができますが、トリガではなくリテラルを使用することができます。

また、サーバーのラウンドトリップを最小限に抑えたい場合は、削除するタスクを一番下まで移動してから他のものを上に移動してから削除することもできますが、それはあまりにも複雑です。

2

TaskOrderをソートに使用している場合は、単にアイテムを削除してもソートが正しく行われないため、TaskOrderに穴を残す方が簡単です。しかし、私はあなたのアプリケーションのニーズについて確かではありません。

0

直接ではありません。これは子ノードを親ノードから「ハングアップ」しているTopological Sortです。子どもの中に依存関係がない場合、実行される順序は関係ありません。子供が特定の順序で実行されなければならない場合、あなたはこれを推論するのに十分な情報を持っていません - 階層の追加レベルを持たなければなりません。

親の中の子供の順序が無関係であると仮定すると、トポロジカルな並べ替えが必要なものを得るでしょう。あなたはほとんどの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; 

、あなたは削除を排除し、単に将来の報告目的のために転がっ記録を残すことができます。

警告:テストされていません!

関連する問題