4

Oracle クエリについてサポートが必要です。

これが私のセットアップです:

それぞれ「タスク」と「タイムシート」と呼ばれる2つのテーブルがあります。「タスク」テーブルは再帰的なもので、各タスクが複数のサブタスクを持つことができます。各タイムシートはタスク (「ルート」タスクとは限りません) に関連付けられており、その作業にかかった時間数が含まれています。

例:

タスク

id:1 | 名前: タスク A | 親 ID: NULL

id:2 | 名前: タスク A1 | 親 ID: 1

id:3 | 名前: タスク A1.1 | 親 ID: 2

id:4 | 名前: タスク B | 親 ID: NULL

id:5 | 名前: タスク B1 | 親 ID: 4

タイムシート

id:1 | タスク ID: 1 | 時間: 1

id:2 | タスク ID: 2 | 時間: 3

id:3 | タスク ID:3 | 時間: 1

id:5 | タスク ID:5 | 時間:1 ...

私がしたいこと:

「タスク階層」で働いたすべての時間の合計を返すクエリが必要です。前の例を見ると、次の結果が必要であることを意味します。

タスク A - 5 時間 | タスク B - 1 時間

まずはこれでやってみた

SELECT TaskName, Sum(Hours) "TotalHours" 
FROM (
    SELECT replace(sys_connect_by_path(decode(level, 1, t.name), '~'), '~') As TaskName, 
    ts.hours as hours
    FROM tasks t INNER JOIN timesheets ts ON t.id=ts.task_id
    START WITH PARENTOID=-1
    CONNECT BY PRIOR t.id = t.parent_id
    )
GROUP BY TaskName Having Sum(Hours) > 0 ORDER BY TaskName

そして、それはほとんど機能します。唯一の問題は、ルート タスクのタイムシートがない場合、階層全体がスキップされることですが、子行のタイムシートが存在する可能性があり、まさにタスク B1 で発生します。私の問題を引き起こしているのは「内部結合」部分であることはわかっていますが、どうすればそれを取り除くことができるかわかりません。

この問題を解決する方法はありますか?

ありがとうございました

4

3 に答える 3

4

このようなものは機能しますか?あなたと似たようなケースがありましたが、行が失われないように、階層クエリから結合を削除し、後でのみ適用しました。

SELECT TaskName, Sum(ts.hours) "TotalHours" 
FROM (
    SELECT replace(sys_connect_by_path(decode(level, 1, t.name), '~'), '~') As TaskName, t.id
    FROM tasks t
    START WITH PARENTOID=-1
    CONNECT BY PRIOR t.id = t.parent_id
    ) tasks
INNER JOIN timesheets ts ON tasks.id=ts.task_id
GROUP BY TaskName Having Sum(ts.hours) > 0 ORDER BY TaskName
于 2010-05-27T15:14:40.873 に答える
1

Have you tried this?

SELECT TaskName, Sum(Hours) "TotalHours" 
FROM (
    SELECT replace(sys_connect_by_path(decode(level, 1, t.name), '~'), '~') As TaskName, 
    ts.hours as hours
    FROM timesheets ts  LEFT OUTER JOIN tasks t  ON t.id=ts.task_id
    START WITH PARENTOID=-1
    CONNECT BY PRIOR t.id = t.parent_id
    )
GROUP BY TaskName Having Sum(Hours) > 0 ORDER BY TaskName
于 2010-05-27T15:18:52.187 に答える
0

通常の結合の代わりに左外部結合を使用すると、出力が得られる場合があります。

SELECT TaskName, Sum(Hours) "TotalHours"  
FROM ( 
    SELECT replace(sys_connect_by_path(decode(level, 1, t.name), '~'), '~') As TaskName,  
    ts.hours as hours 
    FROM tasks t,timesheets ts where t.id=ts.task_id(+) 
    START WITH PARENTOID=-1 
    CONNECT BY PRIOR t.id = t.parent_id 
    ) 
GROUP BY TaskName Having Sum(Hours) > 0 ORDER BY TaskName 
于 2010-05-27T15:07:31.560 に答える