题
我需要Oracle查询的帮助。
这是我的设置:
我分别有2个名为“任务”和“时间表”的表。 “任务”表是一个递归的表,这样每个任务都可以具有多个子任务。每个时间表都与任务相关联(不一定是“ root”任务),并包含在其上工作的小时数。
例子:
任务
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
而且几乎可以工作。唯一的问题是,如果没有针对根任务的时间表,它将跳过整个HiEararchy ...但是可能有子行的时间表,这正是任务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
不隶属于 StackOverflow