4

我需要有关 oracle 查询的帮助。

这是我的设置:

我有 2 个表,分别称为“任务”和“时间表”。“任务”表是一个递归表,这样每个任务可以有多个子任务。每个时间表都与一个任务(不一定是“根”任务)相关联,并包含在其上工作的小时数。

例子:

任务

编号:1 | 名称:任务A | parent_id:空

编号:2 | 名称:任务A1 | parent_id:1

编号:3 | 名称:任务 A1.1 | parent_id:2

编号:4 | 名称:任务B | parent_id:空

编号:5 | 名称:任务 B1 | parent_id:4

时间表

编号:1 | 任务ID:1 | 小时:1

编号:2 | 任务ID:2 | 小时:3

编号:3 | 任务ID:3 | 小时:1

编号: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

你试过这个吗?

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 回答