Verschiedene Datumswerte analysieren und korrekt ausgeben

ja, hast recht, habs mal mit 15 joins gemacht, mit einem join und max() war die Zeit 0,75s und mit 15 joins war es 1,03s. also 25% langsamer. Ich werde schauen ob das erträglich bleibt, wenn ich die Datenmenge erhöhe. Bei einer Auswertung mit "live"-Daten bin ich bis 4 Sekunden einverstanden, war darüber ist, muss wie du schon angemerkt hast, dass die Daten in eine Tabelle abspeichern und in der Nacht aktualisieren lassen.


Ich denke, ich bin jetzt am letzten Punkt, hier verstehe ich etwas nicht, überlege schon, aber weiß nicht weiter:

Ich mach einen left join auf eine Tabelle. In der Tabelle stehen die gearbeiteten Stunden des Mitarbeiters. Ich wollte gern die Summe der gearbeiteten Stunden für den Phasenbereich ausgeben. Ich dachte mir das ist doch ganz einfach 🙃

Wenn ich:

Code:
select personalnr, sum(stunden) as gesamtstunden
from stundentabelle
where personalnr = 11917 and von >= '2018-12-03' and bis <= '2019-01-13'
group by personalnr

Erhalte ich dir korrekte Summe der Stunden.

Wenn ich aber das jetzt in mein Select mit einbiden will, wo ich die Phasen (phase von = 03.12.2018 und phase bis = 13.01.2019) habe:
Code:
select t.personalnr, t.phasevon, t.phasebis, sum(t2.stunden) as gesamtstunden
from t
left join stundentabelle t2 on t.personalnr = t2.personalnr and t2.von >= t.phasevon and t2.bis <= t.phasebis
group by t.personalnr, t.phasevon, t.phasebis

bekomme ich das dreifache... ich finde keine Ursache dazu.
 
Werbung:
du kannst mit "join_collapse_limit" spielen, steht default auf 8. Wenn Du das erhöst wächst zwar die Planungszeit, aber vielleicht findet er einen besseren Plan. Testen.
 
Der Join vervielfacht die Anzahl der Datensätze, ohne die Details genau angesehen zu haben: normalerweise löst man das dadurch, dass man zum Ergebnis der Gruppierung den Join macht. Irgendwas in der Art:

Code:
select t.personalnr, t.phasevon, t.phasebis, t2.gesamtstunden
from t
left join (
  select personalnr, sum(stunden) as gesamtstunden
  from stundentabelle
  where von >= '2018-12-03' and bis <= '2019-01-13'
  group by personalnr
) t2 on t.personalnr = t2.personalnr

Ich bin mir nicht ganz sicher wie das mit dem von/bis zusammengehört
 
Den Join einfach mal stehen lassen und das GROUP BY und die Summe raus nehmen. Dafür stundentabelle.* in den Select:-Teil aufnehmen und schauen, welche Kombination von linker und rechter Tabelle die Dubletten verursachen.
 
Verstehe ich nicht. Dein Statement das "funktioniert" (Beitrag #46 - "Erhalte ich dir korrekte Summe der Stunden.") hat doch das von/bis drin gehabt. Genauso habe ich das doch übernommen.
bei #46 habe ich einmal ein direktes select auf die Stundentabelle mit einem where. Wenn ich darauf joine, habe ich kein where sondern packe es in die join conditions. Dann gehts nicht mehr.

Den Join einfach mal stehen lassen und das GROUP BY und die Summe raus nehmen. Dafür stundentabelle.* in den Select:-Teil aufnehmen und schauen, welche Kombination von linker und rechter Tabelle die Dubletten verursachen.
habe ich exemplarische für eine Phase gemacht wo er 14 Tage gearbeitet hat. Ich bekomme dann 14 Datensätze für diese Phase dann ausgewiesen (03.12.2018 - 13.01.2019)
=> stundentabelle.* = 14 Datensätze
=> stundentabelle.stunden => 14 Datensätze, also wenn ich die Stunden zusammenrechne ergibt das 125h
=> sum(stundentabelle.stunden) => 125h

ich schwöre, hab ich alles schon mal probiert gehabt :-D aber jetzt gehts...

meine Vermutung:

Ich hatte bis heute früh noch einen join wo ich gegen eine Tabelle gegangen bin, wo es 15 Möglichkeiten gab und habe das dann mit einem max() neutralisiert. Dann habe ich gegen 15 statt 1 tabelle gejoint und es gab pro join exakt eine Möglichkeit.

Danach hatte ich das mit den Stunden nicht mehr versucht, und jetzt gehts...


jetzt muss ich nur noch alles zusammenrechnen, ausrechnen und dann ins html bringen :-D

Danke für eure Hilfe!
 
Ja die Tabelle im Join sollte immer nur einen Datensatz pro Join liefern. Sonst dürfte die Performance sinken und die Aggregate sind Blödsinn.

Du kannst '2018-12-03' and bis <= '2019-01-13' mit BETWEEN '2018-12-03' AND '2019-01-13' ersetzen.
 
bei #46 habe ich einmal ein direktes select auf die Stundentabelle mit einem where. Wenn ich darauf joine, habe ich kein where sondern packe es in die join conditions. Dann gehts nicht mehr.
Vielleicht mit einem Lateral Join?

Code:
select t.personalnr, t.phasevon, t.phasebis, t2.gesamtstunden
from stundentabelle t
  left join lateral (
    select sum(ti.stunden) as gesamtstunden
    from stundentabelle ti
    where ti.von >= t.phasevon and ti.bis <= t.phasebis
      and ti.personalnr = t.personalnr
  ) t2 on true
where t.phasevon >= ...
  and t.phasebis <= ...
 
Werbung:
Zurück
Oben