Group y und Werte in ein Array
Hallo,
ich habe ein mysql Problem:
Eine Tabelle mit vielen Datumseinträgen. Sowas wie ein Dienstplan.
2019-02-19|8:00|12:00|Mueller
2019-02-19|12:00|16:00|Schmidt
2019-02-19|16:00|20:00|Meier
2019-02-19|20:00|00:00|Klaus
2019-02-20|8:00|12:00|Schmidt
2019-02-20|12:00|16:00|Meier
2019-02-20|16:00|20:00|Mueller
2019-02-20|20:00|00:00|Klaus
...
Ich möchte nun eine Ausgabe wie:
2019-02-19
08:00-12:00 Müller, 12:00-16:00 Schmidt, 16:00-20:00 Meier, 20:00-0:00 Klaus
2019-02-20
08:00-12:00 Schmidt, 12:00-16:00 Meier, 16:00-20:00 Müller, 20:00-0:00 Klaus
usw.
Mache ich eine normale Abfrage, spuckt er mir 4 Zeilen pro tag raus. Gruppiere ich, schmeisste er mir eine Zeile raus, aber nur den letzten Eintrag von Klaus. Eine Möglichkeit wäre, alles per Sub select in ein mehrdimensionales Array packen, dann ein Foreach durchlaufen lassen, Dann das nächste Datum...
Kriege ich das eleganter hin? Die felder sind id, startzeit, endzeit, kommentar. Es müsste sowas sein wie group by datum und packe startzeiten und endzeiten in ein Array..
Irgendwer eine Idee? Vielen Dank
tsunami
ich habe ein mysql Problem:
Eine Tabelle mit vielen Datumseinträgen. Sowas wie ein Dienstplan.
2019-02-19|8:00|12:00|Mueller
2019-02-19|12:00|16:00|Schmidt
2019-02-19|16:00|20:00|Meier
2019-02-19|20:00|00:00|Klaus
2019-02-20|8:00|12:00|Schmidt
2019-02-20|12:00|16:00|Meier
2019-02-20|16:00|20:00|Mueller
2019-02-20|20:00|00:00|Klaus
...
Ich möchte nun eine Ausgabe wie:
2019-02-19
08:00-12:00 Müller, 12:00-16:00 Schmidt, 16:00-20:00 Meier, 20:00-0:00 Klaus
2019-02-20
08:00-12:00 Schmidt, 12:00-16:00 Meier, 16:00-20:00 Müller, 20:00-0:00 Klaus
usw.
Mache ich eine normale Abfrage, spuckt er mir 4 Zeilen pro tag raus. Gruppiere ich, schmeisste er mir eine Zeile raus, aber nur den letzten Eintrag von Klaus. Eine Möglichkeit wäre, alles per Sub select in ein mehrdimensionales Array packen, dann ein Foreach durchlaufen lassen, Dann das nächste Datum...
Kriege ich das eleganter hin? Die felder sind id, startzeit, endzeit, kommentar. Es müsste sowas sein wie group by datum und packe startzeiten und endzeiten in ein Array..
Irgendwer eine Idee? Vielen Dank
tsunami
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 432480
Url: https://administrator.de/forum/group-y-und-werte-in-ein-array-432480.html
Ausgedruckt am: 05.04.2025 um 11:04 Uhr
11 Kommentare
Neuester Kommentar
Also, die Trennung von Datum, Startzeit und Endzeit ist schon mal Suboptimal. Ideal um sowas abzubilden wären RANGE-Typen, die aber MySQL nicht hat. Ich zeige Dir mal eine Lösung mit einer anderen DB:
test=*# select * from tsunami ;
von_bis | name
-----------------------------------------------+---------
["2019-02-19 08:00:00","2019-02-19 12:00:00") | Mueller
["2019-02-19 12:00:00","2019-02-19 16:00:00") | Schmidt
["2019-02-19 16:00:00","2019-02-19 20:00:00") | Meier
["2019-02-19 20:00:00","2019-02-20 00:00:00") | Klaus
["2019-02-20 08:00:00","2019-02-20 12:00:00") | Schmidt
["2019-02-20 12:00:00","2019-02-20 16:00:00") | Meier
["2019-02-20 16:00:00","2019-02-20 20:00:00") | Mueller
["2019-02-20 20:00:00","2019-02-21 00:00:00") | Klaus
(8 rows)
test=*# select lower(von_bis)::date::text as "Datum", string_agg(extract(hour from lower(von_bis)) || ' - ' || extract(hour from upper(von_bis)) || ': ' || name, ', ') as "Dienstplan" from tsunami group by 1;
Datum | Dienstplan
------------+------------------------------------------------------------------
2019-02-19 | 8 - 12: Mueller, 12 - 16: Schmidt, 16 - 20: Meier, 20 - 0: Klaus
2019-02-20 | 8 - 12: Schmidt, 12 - 16: Meier, 16 - 20: Mueller, 20 - 0: Klaus
(2 rows)
test=*#
das sollte sogar mit den begrenzten Möglichkeiten von MySQL ähnlich wie meine Lösung funktionieren. IIRC gibt es da auch eine String-Aggregation, dazu passend den String zusammenbasteln und über das Datum aggregieren. Schleifen sollte man prinzipiell vermeiden, diese führen bei wachsenden Datenmengen sehr schnell zu extremen Reaktionszeiten.
Ungewöhnlich, normal sind doch mehr Spalten immer besser. Ich teste mal...
Wo hast Du das gelernt?
Da die Zeiten nicht immer gleich sind, gehören Datum und Zeit zusammen und bilden einen Timestamp. Da es außerdem noch um Zeitbereiche geht (von, bis) wäre die Angabe als RANGE noch besser (wie von mir gezeigt), nur kann MySQL das natürlich nicht. Mittels RANGE könntest Du hier sogar einen Constraint setzen, daß sich niemals die Schichten von 2 oder mehr Leuten überschneiden. Das mag hier vielleicht keinen Sinn machen, aber z.B. bei einem Hotel wäre es peinlich, wenn ein und dasselbe Zimmer doppelt belegt wird. Das geht sehr einfach via RANGE-Typen zu vermeiden.
Da ich in Zeile 9 ein "string_agg" sehe vermute ich mal, Du hast ohne zu lesen, was ich schrieb, einfach per Copy&Paste mein gezeigtes SQL übernommen. Ja, das ist für eine andere, bessere Datenbank bestimmt. Schrieb ich auch.
Was Du machen solltest: Dir das Grundprinzip anschauen.
Übrigens: wenn Du schreibst: "Gruppiere ich, schmeisste er mir eine Zeile raus, aber nur den letzten Eintrag von Klaus. " dann ist das eine relativ wertlose Information hier, weil keiner weiß, was Du *genau* versucht hast. MySQL führt syntaktisch falsche Abfragen mit Gruppierung aus und liefert ein falsches Resultat. Korrekt wäre eine Fehlermeldung. Keine Ahnung, was für komisches Kraut die da rauchen ...
Was Du machen solltest: Dir das Grundprinzip anschauen.
Übrigens: wenn Du schreibst: "Gruppiere ich, schmeisste er mir eine Zeile raus, aber nur den letzten Eintrag von Klaus. " dann ist das eine relativ wertlose Information hier, weil keiner weiß, was Du *genau* versucht hast. MySQL führt syntaktisch falsche Abfragen mit Gruppierung aus und liefert ein falsches Resultat. Korrekt wäre eine Fehlermeldung. Keine Ahnung, was für komisches Kraut die da rauchen ...
Hallo zusammen,
wieviele Zeitfenster gibt es denn? Sind es immer glatte Zeiten?
Dann würde ich so vorgehen:
Tabelle:
datum schicht mitarbeiter
2019-02-19 08:00-12:00 Mueller
2019-02-19 12:00-16:00 Schmidt
2019-02-19 16:00-20:00 Meier
2019-02-20 08:00-12:00 Schmidt
2019-02-20 12:00-16:00 Meier
2019-02-20 16:00-20:00 Mueller
2019-02-20 20:00-00:00 Klaus
2019-02-19 20:00-00:00 Klaus
Abfrage:
Ergebnis:
datum 08:00-12:00 12:00-16:00 16:00-20:00 20:00-00:00
2019-02-19 Mueller Schmidt Meier Klaus
2019-02-20 Schmidt Meier Mueller Klaus
Liste der Schichten kann dann natürlich erweitern werden.
Mit MS SQL getestet, sollte auch mit MySQL gehen.
Gruß thejoker230580
wieviele Zeitfenster gibt es denn? Sind es immer glatte Zeiten?
Dann würde ich so vorgehen:
Tabelle:
datum schicht mitarbeiter
2019-02-19 08:00-12:00 Mueller
2019-02-19 12:00-16:00 Schmidt
2019-02-19 16:00-20:00 Meier
2019-02-20 08:00-12:00 Schmidt
2019-02-20 12:00-16:00 Meier
2019-02-20 16:00-20:00 Mueller
2019-02-20 20:00-00:00 Klaus
2019-02-19 20:00-00:00 Klaus
Abfrage:
select
distinct s.datum,
m1.mitarbeiter as '08:00-12:00',
m2.mitarbeiter as '12:00-16:00',
m3.mitarbeiter as '16:00-20:00',
m4.mitarbeiter as '20:00-00:00'
from
dbo.schichten s
left join
dbo.schichten m1 on s.datum = m1.datum and m1.schicht = '08:00-12:00'
left join
dbo.schichten m2 on s.datum = m2.datum and m2.schicht = '12:00-16:00'
left join
dbo.schichten m3 on s.datum = m3.datum and m3.schicht = '16:00-20:00'
left join
dbo.schichten m4 on s.datum = m4.datum and m4.schicht = '20:00-00:00'
order by s.datum
Ergebnis:
datum 08:00-12:00 12:00-16:00 16:00-20:00 20:00-00:00
2019-02-19 Mueller Schmidt Meier Klaus
2019-02-20 Schmidt Meier Mueller Klaus
Liste der Schichten kann dann natürlich erweitern werden.
Mit MS SQL getestet, sollte auch mit MySQL gehen.
Gruß thejoker230580
Oder so:
Ergebnis:
datum Schichtplan
2019-02-19 Mueller 08:00-12:00 Schmidt 12:00-16:00 Meier 16:00-20:00 Klaus 20:00-00:00
2019-02-20 Schmidt 08:00-12:00 Meier 12:00-16:00 Mueller 16:00-20:00 Klaus 20:00-00:00
select
distinct s.datum,
m1.mitarbeiter + ' '+'08:00-12:00' + ' '+
m2.mitarbeiter + ' '+ '12:00-16:00' + ' '+
m3.mitarbeiter + ' '+ '16:00-20:00' + ' '+
m4.mitarbeiter + ' '+ '20:00-00:00' as Schichtplan
from
dbo.schichten s
left join
dbo.schichten m1 on s.datum = m1.datum and m1.schicht = '08:00-12:00'
left join
dbo.schichten m2 on s.datum = m2.datum and m2.schicht = '12:00-16:00'
left join
dbo.schichten m3 on s.datum = m3.datum and m3.schicht = '16:00-20:00'
left join
dbo.schichten m4 on s.datum = m4.datum and m4.schicht = '20:00-00:00'
order by s.datum
select *
FROM dbo.schichten
Ergebnis:
datum Schichtplan
2019-02-19 Mueller 08:00-12:00 Schmidt 12:00-16:00 Meier 16:00-20:00 Klaus 20:00-00:00
2019-02-20 Schmidt 08:00-12:00 Meier 12:00-16:00 Mueller 16:00-20:00 Klaus 20:00-00:00