Antwort an „Rolf B“ verfassen

Hallo Mathias,

ich versuche mal, dein Problem zu strukturieren.

Was ich derzeit mache, ist eine solche Datenbankabfrage mit einer Where Klausel, die mir immer genau einen DS liefert.

Das heißt: Dein Datenbeispiel vom Anfang ist das Ergebnis dieser DB-Abfrage, aber ohne WHERE-Klausel?

Der eine Wert ist eine Mitarbeiter ID der andere eine ID aus der VOB.

Index 0 ist die Mitarbeiter-ID und Index 1 ist die VOB-ID?

Vorschlag 1: Lies die Daten mit fetch_assoc (mysqli) oder der FETCH_ASSOC-Option (PDO), dann sind das keine numerischen Indizes, sondern die Indizes auf Ebene 2 entsprechen den Spaltennamen aus dem SELECT Statement. Wenn Dir die Spaltennamen aus dem SELECT im PHP nicht gefallen, oder wenn Du Spalten in der Query hast, die keinen Namen haben (bei Berechnungen), verwende in der SELECT-Liste die AS Klausel, um eigene Spaltennamen zu vergeben.

Meine Schleife durchläuft jetzt die Mitarbeiter und gibt zu jedem einen Wert aus den VOB-IDs aus. ... (Der) Aufbau in der Statistik (erfolgt) pro Mitarbeiter auf der X Achse

Du erstellst eine Tabelle, mit einer Spalte je Mitarbeiter und eine Zeile pro VOB-ID?

Es gibt zu jedem Mitarbeiter genau alle VOB-IDs zu einem bestimmten Datum. Es gibt ca. 30 Mitarbeiter und 300 VOB-IDs.

Die Tabelle hat demnach ca. 30 Spalten und 300 Zeilen? Plus Zeilen- und Spaltenüberschriften? Und alle ca. 6000 Datenzellen sind gefüllt, es gibt keine unbelegten Datenzellen?

Wie wäre es denn, wenn du der SQL Abfrage ein ORDER BY spendierst? Ich bleibe mal bei deiner Demotabelle und meiner Annahme für Index 0 und 1.

SELECT ma_id, vob_id, col1, col2, col3, col4
FROM xyz_table
WHERE datum = ...
ORDER BY vob_id, ma_id

Ich habe jetzt höchstens Bedenken, dass die Sortierung nicht nach Mitarbeiter-ID, sondern nach Mitarbeiter-Name erfolgen soll. Und dass die VOB-ID ebenfalls nicht das Sortierkriterium ist, sondern dass es zur ID einen Namen gibt, nach dem sortiert werden soll. Für die Mitarbeiter gibt es sicherlich eine Tabelle mitarbeiter(id, name, vorname), wo sie alle drinstehen. Diese Tabelle kann man zum Sortieren heranziehen:

SELECT ma_id, vob_id, col1, col2, col3, col4
FROM xyz_table
JOIN mitarbeiter ON xyz_table.ma_id = mitarbeiter_id
WHERE datum = ...
ORDER BY vob_id, mitarbeiter.name, mitarbeiter.vorname

Disclaimer: in MYSQL kann man meines Wissens nach einer Spalte sortieren, die im SELECT nicht mitgelistet wird. Andere SQL-Server machen das ggf. anders, in dem Fall musst Du mitarbeiter.name und mitarbeiter.vorname im SELECT mit aufführen.

Eine Sortierung nach VOB-Name statt ID kannst Du ähnlich herbeiführen, wenn es eine Tabelle gibt, wo alle VOB-IDs und ihre Namen drinstehen. Ob das erforderlich ist, musst Du selbst wissen.

Unter der Voraussetzung, dass die Tabelle vollständig ausgefüllt wird, bekommst Du jetzt alle Tabellenzellen in zeilenweiser Reihenfolge geliefert. Falls es Lücken gibt, musst Du noch ein bisschen mehr Hirnschmalz reinstecken, darüber diskutieren wir, wenn Du erklärst, dass es Lücken geben kann, d.h. manche Mitarbeiter eben doch nicht alle VOB-IDs haben.

Was Du jetzt noch programmieren musst, ist ein Gruppenwechsel. Die Theorie dazu hat der Dennis vor 9 Jahren im Self-Wiki aufgeschrieben, ob der Artikel den OmA-Test besteht, weiß ich nicht.

Grundsätzlich brauchst Du:

  • die Initialisierung

    • Tabellenkopf schreiben. Hierfür brauchst Du vermutlich ebenfalls SQL, um eine Liste aller Mitarbeiter zu erhalten und einen Spaltenkopf/MA zu erzeugen. Achte auf die richtige Sortierung!
    • Ma/VOB SQL-Statement ausführen - wirklich nur ausführen! Es gibt immer die Möglichkeit, auf dem Query-Ergebnis fetchAll durchzuführen, das ist aber nicht nötig, wenn die Zeilen genau in der gewünschten Reihenfolge kommen.
    • erste DB-Row lesen (VORLESEN), mit FETCH_ASSOC, nicht FETCH_ARRAY
  • Hauptschleife: WHILE ($row)

  • einen Gruppenvorlauf (pro geschriebener Tabellenzeile)

    • $vob_id = $row['vob_id']; // Speichern der VOB-ID dieser DB-Row
    • Ausgabe von <tr> und Ausgabe eines <th>...</th> als Zeilenüberschrift, vermutlich mit der VOB-ID darin, die in dieser Zeile berichtet wird
  • einen Gruppendurchlauf: WHILE ($vob_id == $row['vob_id'])

    • Erstellen des HTML für die Tabellenzelle, die diese Kombi aus MA-ID und VOB-ID berichtet
    • Ausgeben des fertigen <td>...</td> für diese Zelle
    • Lesen der nächsten Row (NACHLESEN) = Nächster Mitarbeiter zur VOB-ID oder erster Mitarbeiter zur nächsten VOB-ID. Falls die VOB-ID wechselt, sorgt das WHILE-Statement für das Ende des Gruppendurchlaufs
    • Ende der Gruppendurchlauf-Schleife
  • einen Gruppennachlauf

    • </tr> ausgeben. Möglicherweise schreibst Du vorher noch weitere Spalten? Keine Ahnung wie deine Tabelle aussieht
  • Ende der Hauptschleife

Das ist eine Programmiertechnik aus den 60er Jahren, aber auch heute noch relevant. Vorteil: Du hast nie mehr als eine Row im Speicher, die HTML-Antwort wird sozusagen „durchgestreamt“.

Anders ist es, wenn die Tabelle Lücken hat. In diesem Fall kann es einfacher sein, zunächst alle Rows zu lesen und sie in eine PHP-Tabelle umzukopieren, die passend zur Ausgabe strukturiert ist (Speicher für 6000 DB-Zeilen ist kein Problem, bei 6 Millionen Zeilen wäre das anders, aber die würde ich ohne Paging-Verfahren auch nicht auf eine HTML Seite ausgeben).

Das Umkopieren kostet nicht viel Zeit und kaum zusätzlichen Speicher. Solange ein Array nicht geändert wird, kopiert PHP nur eine Referenz darauf und nicht das ganze Array. Aber, wie gesagt, darüber reden wir wenn es nötig ist, das ist erstmal unnötiger Aufwand.

Rolf

--
sumpsi - posui - obstruxi
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar
freiwillig, öffentlich sichtbar

Ihre Identität in einem Cookie zu speichern erlaubt es Ihnen, Ihre Beiträge zu editieren. Außerdem müssen Sie dann bei neuen Beiträgen nicht mehr die Felder Name, E-Mail und Homepage ausfüllen.

abbrechen