3

隣接リスト モデル (以下を参照) を使用する「タスク リスト」データベースがあるので、各「タスク」は無制限のサブタスクを持つことができます。テーブルには「TaskOrder」列があるため、すべてがツリービューで正しい順序でレンダリングされます。

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

タスクテーブル
----------
タスク ID
親タスク ID
TaskOrder
タスク名
- 等 - 

何か案は?ありがとう。

4

5 に答える 5

2

並べ替えに TaskOrder のみを使用している場合は、TaskOrder に穴をそのままにしておく方が簡単です。項目を削除するだけでは並べ替えが正しく行われないからです。しかし、あなたのアプリケーションのニーズについてはわかりません。

于 2008-09-29T17:10:24.317 に答える
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をキャプチャし、行を削除してから、トリガーではなくリテラルを使用して同じ更新ステートメントを実行できます。

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

于 2008-09-29T22:04:20.287 に答える
0

直接ではありません。これは、子ノードを親から「吊るす」トポロジカル ソートです。子に依存関係がない場合、それらが実行される順序は重要ではありません。子を特定の順序で実行する必要がある場合、これを推測するのに十分な情報がありません。追加の階層レベルが必要になります。

親内の子の順序が無関係であると仮定すると、トポロジカルな並べ替えにより、必要なものが得られます。ほとんどの SQL ダイアレクトでは、これを 1 つのクエリにまとめることはできません。これを行うには、sproc を作成する必要があります。

ノード内の子の順序が適切である場合は、親内でタスクの順序を維持する必要があります。ParentNodeID、TaskOrder、およびカウント (*) を使用したクエリは重複を選択しますが、システムがタスクを並べ替えるための追加情報を持っていない限り、正しい順序を選択するために手動で介入する必要があります。

何かを明確にしたい場合は、コメントを追加してください。

于 2008-09-29T17:14:07.490 に答える
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
于 2008-09-29T17:14:34.197 に答える
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;

もちろん、削除を省略して、将来のレポート目的のためにレコードをそのままにしておくこともできます。

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

于 2008-09-29T17:15:12.917 に答える