0

MS Project Server を使用してレポートを作成していますが、問題が発生しました。親子階層のいくつかのフィールドを合計する必要があります。合計は、葉の値の合計です。クエリを作成しましたが、小さなデータ セットでしか機能していません。

Task - 10
  Task - 2
  Task - 6
    Task - 6
  Task - 2

WITH children AS (
SELECT 
tt.ID, 
CASE '1' WHEN ISNULL(ttt.Id, '1') THEN tt.Value ELSE 0 END as Value,
CASE '1' WHEN ISNULL(ttt.Id, '1') THEN tt.Value2 ELSE 0 END as Value2,
tt.parentid
    FROM [MonitoringExampleDatabase].[dbo].[Table_1] tt
    LEFT JOIN [MonitoringExampleDatabase].[dbo].[Table_1] ttt 
    ON tt.ID = ttt.ParentId

UNION ALL

SELECT t.id, children.value, children.Value2, t.parentid
    FROM children 
    JOIN [MonitoringExampleDatabase].[dbo].[Table_1] t ON children.parentid = t.id
)

SELECT  id, sum(value) as Value, SUM(value2) as Value2
    FROM children 
    GROUP BY id

そのクエリを最適化する方法についてのアイデアはありますが、問題は再帰の制限です。

4

2 に答える 2

1

子の最初の SELECT での結合は間違った方法ですか? コードを実行すると、集計されていないデータが返されます。

id          Value       Value2
----------- ----------- -----------
1           10          0
2           2           0
3           6           0
4           6           0
5           2           0

これは、次のようにテーブルをセットアップした方法が原因である可能性があります。

CREATE TABLE [dbo].[Tasks](
[Id] [int] NULL,
[ParentId] [int] NULL,
[Value] [int] NULL,
[Value2] [int] NULL
) ON [PRIMARY]

子の最初の SELECT をそのようにリファクタリングすると、望ましい結果であると推測されるものが得られます。

WITH children AS (
    SELECT 
      c.ID, 
      c.Value,
      c.Value2,
      c.parentid
    FROM Tasks c
      LEFT JOIN Tasks p
        ON c.ParentId = p.Id

UNION ALL

    SELECT t.id, children.value, children.Value2, t.parentid
        FROM children 
        INNER JOIN Tasks t ON children.parentid = t.id
)

SELECT  id, sum(value) as Value, SUM(value2) as Value2
    FROM children 
    GROUP BY id

結果:

id          Value       Value2
----------- ----------- -----------
1           26          0
2           2           0
3           12          0
4           6           0
5           2           0

パフォーマンスに関しては、一般的に言えば、多くのレベルがある場合、再帰アルゴリズムは遅くなります。可能な最大レベル数を知っている限り、速度を向上させるために反復バージョンにリファクタリングできます。

反復コードは、再帰コードほどきれいでも簡潔でもありませんが、おそらく理解しやすいです (したがって維持します)。

于 2013-04-12T11:23:34.103 に答える