一緒にミキシングすることで接続し、内側の結合と合計をOracleと合計します
-
05-10-2019 - |
質問
Oracleのクエリでサポートが必要です。
これが私のセットアップです:
それぞれ「タスク」と「タイムシート」と呼ばれる2つのテーブルがあります。 「タスク」テーブルは再帰的なものです。そのため、各タスクには複数のサブタスクがあります。各タイムシートはタスク(必ずしも「ルート」タスクではない)に関連付けられており、それに取り組んでいる時間数が含まれています。
例:
タスク
ID:1 |名前:タスクA | parent_id:null
ID:2 |名前:タスクA1 | Parent_id:1
ID:3 |名前:タスクA1.1 | Parent_id:2
ID:4 |名前:タスクB | parent_id:null
ID:5 |名前:タスクB1 | Parent_id:4
タイムシート
ID:1 | task_id:1 |時間:1
ID:2 | task_id:2 |時間:3
ID:3 | task_id:3 |時間:1
ID:5 | task_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で起こることです。私の問題を引き起こしているのは「内部結合」の部分であることは知っていますが、どうすればそれを取り除くことができるかわかりません。
この問題を解決する方法はありますか?
ありがとうございました
解決
このようなものは機能しますか?私はあなたのものに似たケースを持っています、そして、私は単に階層クエリから結合を削除し、その後のみそれを適用して、行を失うことを避けました。
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
他のヒント
これを試しましたか?
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
通常の結合の代わりに左外の結合を使用する場合、出力を取得できます。
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