x-herbert: MySQL + PHP => HTML-Tabelle (knifflige Konstruktion...)

Hi,

keine Angst, es kommt nicht die Frage "wie erstelle ich eine Tabelle..."

Folgendes Problem:
1.) ich habe eine MySQL-Tabelle
Datum  | Zeit | Veranstaltung
1.1.03 |16.00 | Veranst_01
2.1.03 |18.00 | Veranst_03
2.1.03 |20.00 | Veranst_04
5.1.03 |16.00 | Veranst_05
8.1.03 |14.00 | Veranst_06
8.1.03 |16.00 | Veranst_07

2.) per PHP werden die Daten ausgelesen und als HTML-Tabelle geschrieben

=> soweit kein Problem, aber...

ich möchte, dass für jedes Datum _nur_eine_ "große Zeile" entsteht (rowspan=n), die aber für Zeit und Veranstaltung jeweils eine separate Zeile hat.

Beispiel:
--------------------------
1.1.03 |16.00 | Veranst_01
--------------------------
2.1.03 |18.00 | Veranst_03
       -------------------
       |20.00 | Veranst_04
--------------------------
5.1.03 |16.00 | Veranst_05
--------------------------
8.1.03 |14.00 | Veranst_06
       -------------------
       |16.00 | Veranst_07
--------------------------

(hoffe, die Leerzeichen bleiben für die Ansicht erhalten...)

Irgendwie fällt mir nichts Brauchbares ein, wie ich die Ausgabeschleife gestalten kann oder den Select gestalte.

Derzeit wird die Sache über
$result = ...query
while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
...
}
ausgegeben.

Für die gewünschte Konstruktion müsste ich aber vor der Ausgabe erst immer eine oder mehrere "while-Runde(n)" weiter laufen, um sicherzustellen, dass das nächste Datum ein neues ist.

Kann man mit einer geschickten SQL-Abfrage schon ermitteln, wie viele gleiche "Datum" kommen?

Gruss x-herbert

  1. Halihallo x-herbert

    Folgendes Problem:
    1.) ich habe eine MySQL-Tabelle
    Datum  | Zeit | Veranstaltung
    1.1.03 |16.00 | Veranst_01

    Datum und Zeit werden mit dem Datentypen DATE bzw. TIME gespeichert, du wirst IMHO
    VARCHAR oder CHAR genommen haben, ansonsten vergiss diesen Absatz.

    ich möchte, dass für jedes Datum _nur_eine_ "große Zeile" entsteht (rowspan=n), die aber für Zeit und Veranstaltung jeweils eine separate Zeile hat.
    Irgendwie fällt mir nichts Brauchbares ein, wie ich die Ausgabeschleife gestalten kann oder den Select gestalte.

    Dein Problem hat nicht's mit der Datenbank zu tun, sondern mit der Verarbeitung über
    PHP.

    Derzeit wird die Sache über
    $result = ...query
    while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    ...
    }
    ausgegeben.

    Das soll so bleiben.

    Für die gewünschte Konstruktion müsste ich aber vor der Ausgabe erst immer eine oder mehrere "while-Runde(n)" weiter laufen, um sicherzustellen, dass das nächste Datum ein neues ist.

    Nein, speichere das letzte Datum. Stimmt es nicht mit dem in dem aktuellen Datensatz
    überein, schreibe das Datum in die 1. Spalte, ansonsten bleibt sie leer.

    Kann man mit einer geschickten SQL-Abfrage schon ermitteln, wie viele gleiche "Datum" kommen?

    Diese Information brauchst du nicht.

    Viele Grüsse

    Philipp

    1. Hi Phillip,

      Datum und Zeit werden mit dem Datentypen DATE bzw. TIME gespeichert, du wirst IMHO
      VARCHAR oder CHAR genommen haben, ansonsten vergiss diesen Absatz.

      => ist als DATE gespeichert

      Dein Problem hat nicht's mit der Datenbank zu tun, sondern mit der Verarbeitung über
      PHP.

      :) ....

      Nein, speichere das letzte Datum. Stimmt es nicht mit dem in dem aktuellen Datensatz überein, schreibe das Datum in die 1. Spalte, ansonsten bleibt sie leer.

      => die Sachen aus dem ersten Duchlauf speichern und erst ausgeben, wenn ein neues Datum "erscheint" _versuche_ ich zu realisieren. :))  Da es sein kann, dass nicht nur zwei sondern auch mehrere Einträge bei einem Datum erscheinen, muss sich die rowspanzahl (rowspan=n, n=2,3,...) erhöhen => das "Gespeicherte" muss also vor der Ausgabe wieder verändert werden... :(

      Gruss

      1. Halihallo x-herbert

        Datum und Zeit werden mit dem Datentypen DATE bzw. TIME gespeichert, du wirst IMHO
        VARCHAR oder CHAR genommen haben, ansonsten vergiss diesen Absatz.
        => ist als DATE gespeichert

        und TIME auch? :)

        Nein, speichere das letzte Datum. Stimmt es nicht mit dem in dem aktuellen Datensatz überein, schreibe das Datum in die 1. Spalte, ansonsten bleibt sie leer.

        => die Sachen aus dem ersten Duchlauf speichern und erst ausgeben, wenn ein neues Datum "erscheint" _versuche_ ich zu realisieren. :))  Da es sein kann, dass nicht nur zwei sondern auch mehrere Einträge bei einem Datum erscheinen, muss sich die rowspanzahl (rowspan=n, n=2,3,...) erhöhen => das "Gespeicherte" muss also vor der Ausgabe wieder verändert werden... :(

        Verstehe, das habe ich übersehen. Der Tipp von Cheatah ansehen, oder zwei SQL-Abfragen:

        SELECT Datum, COUNT(*) AS 'rowspan' FROM MySQLTabelle GROUP BY Datum ORDER BY Datum DESC

        Wenn du dann ein Datum ausgibst kannst du die rowspan gleich aus dem assoc. Array des
        obengenannten Queries auslesen.

        Viele Grüsse

        Philipp

        1. Hi,

          Datum und Zeit werden mit dem Datentypen DATE bzw. TIME gespeichert, du wirst IMHO
          VARCHAR oder CHAR genommen haben, ansonsten vergiss diesen Absatz.
          => ist als DATETIME gespeichert

          SELECT Datum, COUNT(*) AS 'rowspan' FROM MySQLTabelle GROUP BY Datum ORDER BY Datum DESC

          => klingt gut - werde ich mal probieren....

          derzeit habe ich einen kleinen Trick:
          Wenn Datum == Datum_zeile_vorher {
             dann setze font auf Hintergrundfarbe
          }

          .. ist zwar nicht so richtig das Gewünschte (und unter "akademischen Gesichtspunkten" nicht das Eleganteste) - funktioniert aber zunächst...
          .. aber schon beim Drucken fliegt die Sache wieder auf ;-)

          Gruss x-herbert

          1. Hi,

            SELECT Datum, COUNT(*) AS 'rowspan' FROM MySQLTabelle GROUP BY Datum ORDER BY Datum DESC
            => klingt gut - werde ich mal probieren....

            klingt nicht gut. Eine Gruppenfunktion ohne eine Gruppierung wird von einem ordentlichen DBMS _zu Recht_ als Fehler abgelehnt. MySQL mag das durchgehen lassen, deswegen ist es aber nicht richtiger.

            Cheatah

            --
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
            1. Hi Cheatah,

              klingt nicht gut. Eine Gruppenfunktion ohne eine Gruppierung wird von einem ordentlichen DBMS _zu Recht_ als Fehler abgelehnt. MySQL mag das durchgehen lassen, deswegen ist es aber nicht richtiger.

              => verstehe ich noch nicht ganz :((

              ansonnsten funktioniert die Sache - habe nur das "DESC" rausgenommen, da die Daten ja auch aufsteigend sind.

              Gruss x-herbert

              1. Hi,

                klingt nicht gut. Eine Gruppenfunktion ohne eine Gruppierung wird von einem ordentlichen DBMS _zu Recht_ als Fehler abgelehnt.
                => verstehe ich noch nicht ganz :((

                "SELECT spalte, COUNT(*)" ohne "GROUP BY spalte" ist NONO. Böser Hund.

                Cheatah

                --
                X-Will-Answer-Email: No
                X-Please-Search-Archive-First: Absolutely Yes
                1. Hi,
                  "SELECT spalte, COUNT(*)" ohne "GROUP BY spalte" ist NONO. Böser

                  lt. Vorschlag von Phillip

                  SELECT Datum, COUNT(*) AS 'rowspan' FROM MySQLTabelle GROUP BY Datum ORDER BY Datum DESC

                  ist doch "GROUP BY 'Spalte_Datum' " dabei... ????

                  Gruss x-herbert

                  1. Hi,

                    lt. Vorschlag von Phillip
                    ist doch "GROUP BY 'Spalte_Datum' " dabei... ????

                    ja, aber es liefert Dir nicht alle Datensätze, die Du zur Anzeige brauchst, oder?

                    Cheatah

                    --
                    X-Will-Answer-Email: No
                    X-Please-Search-Archive-First: Absolutely Yes
                    1. Hi,

                      lt. Vorschlag von Phillip
                      ist doch "GROUP BY 'Spalte_Datum' " dabei... ????

                      ja, aber es liefert Dir nicht alle Datensätze, die Du zur Anzeige brauchst, oder?

                      => nicht direkt...

                      ich habe eine Lösung mit zwei SQL-Abfragen:

                      1.) $result = MYSQL_QUERY("SELECT * FROM $tabelle ORDER BY Datum")
                      2.) $result_rowspan = MYSQL_QUERY("SELECT Datum, COUNT(*) AS 'rowspan' FROM $tabelle GROUP BY Datum ORDER BY Datum ")

                      sowie zwei Schleifen für die Ausgabe:
                      while($row_rowspan = mysql_fetch_array($result_rowspan, MYSQL_ASSOC)) {  // = 1.)
                           for ($i=0; $i < $row_rowspan[rowspan] ; $i++) { // = 2.)
                           if $i == 0
                             dann
                           oder
                          }
                      }

                      Voraussetzung: alle "Datum" müssen gefüllt sein (ist so), d.h.
                      Anzahl aller einträge = Anzahl aus Query2 * $row_rowspan[rowspan]
                      so dass ich alles erfasst habe....

                      & meine Anzeige sieht so aus wie gewünscht!

                      geht sicher auch anders... :-)

                      Gruss x-herbert

                    2. Halihallo Cheatah

                      lt. Vorschlag von Phillip
                      ist doch "GROUP BY 'Spalte_Datum' " dabei... ????

                      ja, aber es liefert Dir nicht alle Datensätze, die Du zur Anzeige brauchst, oder?

                      Ich schrieb da was von zwei Queries, der genannte und von dir kritisierte hatte den
                      Zweck, die rowspan-Zahl zu "berechnen" und dies tut er sehr wohl, vollständig und
                      korrekt. Der sollte gar keine Daten für die Anzeige selektieren.
                      Oder wolltest du sagen, dass ein zweiter Query etwas zu viel Overhead ist, nur um
                      rowspan zu berechnen?

                      Viele Grüsse

                      Philipp

  2. Hi,

    ich möchte, dass für jedes Datum _nur_eine_ "große Zeile" entsteht (rowspan=n), die aber für Zeit und Veranstaltung jeweils eine separate Zeile hat.

    dieses n zu ermitteln erfordert, dass Du die Daten zwei mal durchgehst. Leichter wäre es, wenn das Ergebnis an der Stelle wie folgt aussehen dürfte:


    2.1.03 |18.00 | Veranst_03

    |20.00 | Veranst_04

    5.1.03 |16.00 | Veranst_05

    Dann würde es reichen, das zuletzt ausgegebene Datum zu speichern und mit dem jeweils auszugebenden zu vergleichen.

    Derzeit wird die Sache über
    while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    ...
    }
    ausgegeben.

    Wenn obiges nicht machbar ist, musst Du an dieser Stelle die Daten speichern, nicht ausgeben, und evtl. zeitgleich die Anzahl der Zeilen pro Datum in ein assoziatives Array speichern. Eine zweite Schleife über die gespeicherten Daten erledigt die Ausgabe.

    Kann man mit einer geschickten SQL-Abfrage schon ermitteln, wie viele gleiche "Datum" kommen?

    Ja. Da Du offenbar MySQL verwendest, muss diese Abfrage aber schon _sehr_ geschickt sein, zumal Subselects (vermutlich?) nicht möglich sind.

    Cheatah

    --
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes