Question

J'ai besoin d'aide avec une requête oracle.

Voici ma configuration:

J'ai 2 tables appelées respectivement « tâches » et « feuilles de temps ». Le tableau « tâches » est une récursive, de cette façon chaque tâche peut avoir plusieurs sous-tâches. Chaque feuille de temps est associée à une tâche (pas nécessairement la tâche « racine ») et contient le nombre d'heures travaillées sur elle.

Exemple:

Tâches

id: 1 | Nom: Groupe A | id_parent: NULL

id: 2 | Nom: Groupe A1 | parent_id: 1

id: 3 | Nom: Tâche A1.1 | parent_id: 2

id: 4 | Nom: Groupe B | id_parent: NULL

id: 5 | Nom: Tâche B1 | parent_id: 4

Timesheets

id: 1 | task_id: 1 | heures: 1

id: 2 | task_id: 2 | heures: 3

id: 3 | task_id: 3 | heures: 1

id: 5 | task_id: 5 | heures: 1 ...

Ce que je veux faire:

Je veux une requête qui renverra la somme de toutes les heures travaillées sur une « hiérarchie des tâches ». Si nous jetons un coup d'œil à l'exemple précédent, cela signifie que je voudrais avoir les résultats suivants:

A la tâche - 5 heure (s) | tâche B - 1 heure (s)

Au début, j'ai essayé cette

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

Et presque le travail. Le seul problème est que s'il n'y a pas pour une tâche timesheet racine, il ignorera toute hieararchy ... mais il pourrait y avoir des feuilles de temps pour les lignes enfants et il est exactement ce qui se passe avec la tâche B1. Je sais que c'est la partie « jointure » qui est à l'origine de mon problème, mais je ne sais pas comment puis-je en débarrasser.

Toute idée de comment résoudre ce problème?

Merci

Était-ce utile?

La solution

Would quelque chose comme ce travail? J'ai eu des cas semblables à la vôtre, et je simplement supprimé la jointure de la requête hiérarchique et appliqué seulement après pour éviter de perdre des lignes.

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

Autres conseils

Avez-vous essayé?

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 vous utilisez jointure externe gauche au lieu de la normale rejoindre, vous pouvez obtenir la sortie.

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 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top