Pregunta

Necesito ayuda con una consulta de Oracle.

Aquí está mi configuración:

Tengo 2 tablas llamadas respectivamente "tareas" y "tabla de tiempos". La tabla de "tareas" es un ser recursivo, de esa manera cada tarea puede tener varias subtareas. Cada parte de horas está asociado a una tarea (no necesariamente la tarea "raíz") y contiene el número de horas trabajadas en él.

Ejemplo:

Tareas

id: 1 | Nombre: Tarea A | parent_id: NULL

id: 2 | Nombre: Tarea A1 | parent_id: 1

id: 3 | Nombre: Tarea A1.1 | parent_id: 2

id: 4 | Nombre: Tarea B | parent_id: NULL

id: 5 | Nombre: Tarea B1 | parent_id: 4

partes de horas

id: 1 | task_id: 1 | hora: 1

id: 2 | task_id: 2 | hora: 3

id: 3 | task_id: 3 | hora: 1

id: 5 | task_id: 5 | hora: 1 ...

Lo que quiero hacer:

Quiero una consulta que devolverá la suma de todas las horas trabajadas en una "jerarquía de tareas". Si echamos un vistazo al ejemplo anterior, Significa me gustaría tener los siguientes resultados:

Una tarea - 5 hora (s) | tarea B - 1 hora (s)

Al principio traté de este

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

Y casi trabajo. El único problema es que si no hay hoja de tiempo para una tarea raíz, se omitirá toda la hieararchy ... pero podría haber tabla de tiempos para las filas secundarias y es exactamente lo que sucede con el Grupo B1. Sé que es la "combinación interna" parte que está causando mi problema pero no estoy seguro de cómo me deshago de ella.

Cualquier idea de cómo resolver este problema?

Gracias

¿Fue útil?

Solución

¿Podría algo así como este trabajo? He tenido casos similares al suyo, y simplemente me quité la unión de la consulta jerárquica y se aplica sólo después para evitar la pérdida de filas.

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

Otros consejos

¿Has probado esto?

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

Si utiliza externa izquierda en lugar de unirse a la normalidad, es posible obtener la salida.

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 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top