我需要有关oracle查询的帮助。
这是我的设置:
我有两个表分别称为“任务”和“时间表”。 “tasks”表是递归的,每个任务可以有多个子任务。每个时间表都与一个任务(不一定是“根”任务)相关联,并包含在其上工作的小时数。
示例:
id:1 | name:任务A | parent_id:NULL
id:2 | name:任务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 ...但是可能有子行的时间表,而这正是Task B1所发生的情况。我知道这是导致我问题的“内部联接”部分,但我不确定如何摆脱它。
知道如何解决这个问题吗?
谢谢
答案 0 :(得分: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
答案 1 :(得分: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 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
答案 2 :(得分: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