Zusammenmischen von Connect durch, innere Verknüpfung und Summe mit Oracle
-
05-10-2019 - |
Frage
Ich brauche Hilfe mit einer Oracle-Abfrage.
Hier ist mein Setup:
Ich habe 2 Tabellen genannt bzw. „Aufgaben“ und „Zeiterfassungen“. Die „Aufgaben“ Tabelle ist eine rekursive ein, auf diese Weise jede Aufgabe mehrere Unteraufgaben haben. Jede Zeiterfassung ist mit einer Aufgabe verbunden ist (nicht unbedingt die „root“ Task) und enthält die Anzahl der Stunden daran gearbeitet.
Beispiel:
Aufgaben
id: 1 | Name: Aufgabe A | parent_id: NULL
id: 2 | Name: Aufgabe A1 | parent_id: 1
id: 3 | Name: Aufgabe A1.1 | parent_id: 2
id: 4 | Name: Aufgabe B | parent_id: NULL
id: 5 | Name: Aufgabe B1 | parent_id: 4
Zeiterfassungen
id: 1 | task_id: 1 | Stunden: 1
id: 2 | task_id: 2 | Stunden: 3
id: 3 | task_id: 3 | Stunden: 1
id: 5 | task_id: 5 | Stunden: 1 ...
Was ich tun möchte:
Ich möchte eine Abfrage, die die Summe aller Stunden auf einer „Task-Hierarchie“ gearbeitet zurück. Wenn wir einen Blick auf das vorherige Beispiel nehmen, bedeutet dies, ich möchte die folgenden Ergebnisse haben:
Aufgabe - 5 Stunde (n) | Aufgabe B - 1 Stunde (n)
Zuerst habe ich versucht, diese
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
Und es fast Arbeit. Das einzige Problem ist, dass, wenn es keine Zeiterfassung für eine Wurzel Aufgabe ist, wird es die ganze hieararchy überspringt ... aber es könnte Zeiterfassungen für die untergeordneten Zeilen, und es ist genau das, was mit dem Task-B1 passiert. Ich weiß, es ist der „innere Verknüpfung“ Teil, das mein Problem verursacht, aber ich bin nicht sicher, wie kann ich es loswerden.
Jede Idee, wie dieses Problem zu lösen?
Danke
Lösung
wäre so etwas wie dieses Werk? Ich habe Fälle ähnlich wie bei Ihnen gehabt, und ich einfach dem aus der hierarchischen Verknüpfungsabfrage entfernt und wandte sie nur danach Reihen zu verlieren zu vermeiden.
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
Andere Tipps
Haben Sie versucht das?
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
Wenn Sie linke äußere verwenden beitreten anstelle der normalen verbinden, können Sie die Ausgabe erhalten.
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