kim n.: suche sinnvolles Konzept für DB-Tabelle

Hallo,

mir fehlt die Erfahrung (und damit die Routine und der Weitblick), was das Konzeptionieren von DB-Tabellen (mysql) angeht.

Für eine Auflistung von Veranstaltungen haben ich folgende Tabelle angelegt:

Tabelle 1:
id,kategorie,ueberschrift,kurzbeschreibung,preis,status

In einer 2. Tabelle wollte ich nun die Termine der Veranstaltungen auflisten. Dabei ergibt sich für mich folgendes konzeptionelles Problem (auch im Hinblick auf die spätere Suchfunktion nach Monat:

Veranstaltung 1 (12-tägig):
12.06.06 - 24.06.06
26.06.06 - 08.07.06
10.07.06 - 22.07.06
24.07.06 - 05.08.06
07.08.06 - 19.08.06
21.08.06 - 02.09.06

Veranstaltung 2 (5-tägig):
Beginn: jeden Sa von April - Oktober

Veranstaltung 3 (3-tägig):
12.07.06 - 15.07.06
12.12.06 - 15.12.06

1. Frage:
Ist es sinnvoll alle 40 Veranstaltungen in einer Termin-Tabelle aufzulisten? Und wie soll diese dann aussehen (Feldtyp-auch im Hinblick auf Suche nach Monat)? (Spalten: veranstaltungsID, Termin-Start, Termin-Ende, status(falls Termin entfällt))

2. Frage:
Wie kann ich anschließend schauen, ob das Startdatum einer Veranstaltung in einem gewünschten Monat liegt?

Wäre für eine Anregung dankbar

Beste Grüße
Kim N.

----

Danke

  1. Hallo Kim,

    verstehe ich dich richtig, dass es feste Termine im Jahr gibt an denen Veranstaltungen durchgeführt werden? (Tabelle 2)

    Sollte dem so sein, fehlt dir noch ein Bezug zwischen Veranstaltungsdatum und Veranstaltung.

    so long
    Ole
    (8-)>

    --
    Trotz Equalizer und Compressor, der Sound wird matschig unn nett
    bässer!
    1. Hallo Ole,

      ja, es gibt feste Termine (Tabelle 2)

      Sollte dem so sein, fehlt dir noch ein Bezug zwischen Veranstaltungsdatum und Veranstaltung.

      Den Bezug wollte ich über die veranstaltungsID herstellen.
      (Tabelle 1: id -> Tabelle 2: veranstaltungsID)

      Hast du vielleicht noch eine Idee, wie ich die Suche realisieren soll? In welchem Format (Feldtyp) sollte ich die Termine speichern, damit ich schauen kann, welche Veranstaltungen z.b. im Dezember (also 12) stattfinden?

      gruß
      kim

  2. n'abend,

    1. Frage:
      Ist es sinnvoll alle 40 Veranstaltungen in einer Termin-Tabelle aufzulisten? Und wie soll diese dann aussehen (Feldtyp-auch im Hinblick auf Suche nach Monat)? (Spalten: veranstaltungsID, Termin-Start, Termin-Ende, status(falls Termin entfällt))

    sofern du für jede veranstaltung mehrere Termine hast, bietet es sich an eine eigene tabelle für die termine zu erstellen. deine spalten sehen schon mal nicht schlecht aus, kommt halt drauf an was du zu den terminen noch speichern willst.

    für terminStart und TerminEnde würde ich zu Date raten.

    Date Datentyp

    1. Frage:
      Wie kann ich anschließend schauen, ob das Startdatum einer Veranstaltung in einem gewünschten Monat liegt?

    Date Funktionen

    weiterhin schönen abend...

    --
    wer braucht schon großbuchstaben?
    sh:( fo:# ch:# rl:° br:> n4:& ie:{ mo:} va:) de:] zu:} fl:{ ss:? ls:[ js:|
    1. n'abend,

      1. Frage:
        Wie kann ich anschließend schauen, ob das Startdatum einer Veranstaltung in einem gewünschten Monat liegt?
        Date Funktionen

      meiner würde das per folgendem machen..
      SELECT clumns FROM table WHERE date_column LIKE ('2005-12-%')
      oder
      SELECT clumns FROM table WHERE date_column BETWEEN '2005-12-01' AND '2005-12-31'

      (warum die erneute antwort? weil das manual diesbezüglich etwas arg plöt ist)

      weiterhin schönen abend...

      --
      wer braucht schon großbuchstaben?
      sh:( fo:# ch:# rl:° br:> n4:& ie:{ mo:} va:) de:] zu:} fl:{ ss:? ls:[ js:|
      1. Hallo globe,

        danke für diese Antwort ;)
        Ich denke damit kann ich weiterarbeiten.

        Grüße
        Kim

      2. Hallo,

        meiner würde das per folgendem machen..
        SELECT clumns FROM table WHERE date_column LIKE ('2005-12-%')
        oder
        SELECT clumns FROM table WHERE date_column BETWEEN '2005-12-01' AND '2005-12-31'

        wobei die zweite Variante vorzuziehen wäre. Ich denke, die LIKE - Funktion dürfte sehr Perormance-Lastig sein und hier einfach nicht nötig. Wenn Du das als Datentypen DATE verwendest, geht auch folgende Alternative:
        SELECT clumns FROM table WHERE DATE_FORMAT(date_column, '%m') = 12
        (evtl. die 12 in Hochkamma, bin mir da gerade nicht sicher)

        Die Abfrage mit BETWEEN dürfte aber die schnellste sein.

        Schöne Grüße
        Axel

        1. Hallo,

          SELECT clumns FROM table WHERE date_column LIKE ('2005-12-%')
          SELECT clumns FROM table WHERE date_column BETWEEN '2005-12-01' AND '2005-12-31'
          Wenn Du das als Datentypen DATE verwendest, geht auch folgende Alternative:
          SELECT clumns FROM table WHERE DATE_FORMAT(date_column, '%m') = 12

          nur als Anmerkung: MySQL kennt die Funktion MONTH(). Es ist bestimmt keine schlechte Idee, diese zu verwenden :-)

          Dass man Datumsangaben in DATE-Feldern speichert, sollte selbstverständlich sein.

          Freundliche Grüße

          Vinzenz

        2. yo,

          Ich denke, die LIKE - Funktion dürfte sehr Perormance-Lastig sein und hier einfach nicht nötig.

          sollte beides genauso schnell sein, da LIKE und Between falls vorhanden über den gleichen index gehen. man kann nicht sagen das LIKE grundsätzlich problematisch ist, sondern nur bestimmte anwendungen davon, wie zum beispiel ein vorangestelltes % zeichen.

          Ilja

  3. Hallo nochmal...

    nun hat sich mir eine andere Wissenslücke eröffnet:

    Thema joins:

    wie bringe ich es jetzt fertig, dass mir _alle_ termine _einer_ veranstaltung angezeigt werden (die Suchfunktion soll zunächst nicht berücksichtigt werden)

    so sieht es zur zeit aus:

      
      
      
    $sql = "SELECT a.ueberschrift, b.beginn, b.ende FROM veranstaltungen a, termine b WHERE a.id = b.vid";  
      
    $result = mysql_query($sql) OR die(mysql_error());  
    if(mysql_num_rows($result)) {  
     while($row = mysql_fetch_assoc($result)) {  
      echo "<h3>".htmlentities($row['headline'])."</h3>\n";  
      
      
    // PROBLEM:  wie werden anschließend alle Zeilen aus Tabelle 2 (Termine) gelesen, wo a.id = b.vid?  
      
      echo "von: ".$row['beginn']." bis: ".$row['ende'];  
     }  
    }  
    
    

    gruß kim

    1. Hallo Kim,

      nun hat sich mir eine andere Wissenslücke eröffnet:
      Thema joins:

      dazu empfehle ich Dir die geplanten Feature-Artikel von Rouven und mir (ja, etwas Eigenwerbung muss auch sein). Links zu den Reviewversionen gibt es in diesem Archivposting von Tim.

      wie bringe ich es jetzt fertig, dass mir _alle_ termine _einer_ veranstaltung angezeigt werden (die Suchfunktion soll zunächst nicht berücksichtigt werden)
      so sieht es zur zeit aus:

        
      
      > SELECT a.ueberschrift, b.beginn, b.ende FROM veranstaltungen a, termine b WHERE a.id = b.vid";  
      
      

      schreibst Du schöner (und gleich funktional):

        
      SELECT  
        ueberschrift,  
        beginn  
        ende  
      FROM veranstaltungen v     -- v wie _v_eranstaltungen  
      INNER JOIN termine t       -- t wie _t_ermine  
      ON v.id = t.vid  
      
      

      PROBLEM:  wie werden anschließend alle Zeilen aus Tabelle 2 (Termine) gelesen, wo a.id = b.vid?

      Das verstehe ich nicht ganz. Diese Anweisung liefert Dir bereits alle Termine aller Veranstaltungen. Möchtest Du nur eine bestimmte Veranstaltung haben, so filterst Du diese mit Hilfe der WHERE-Klausel aus:

        
      SELECT  
        ueberschrift,  
        beginn  
        ende  
      FROM veranstaltungen v  
      INNER JOIN termine t  
      ON v.id = t.vid  
      WHERE v.id = <die id der speziellen Veranstaltung>  
      
      

      Nun erhältst Du alle Termine dieser speziellen Veranstaltung.

      Freundliche Grüße

      Vinzenz

      1. Hallo

        SELECT
          ueberschrift,
          beginn
          ende
        FROM veranstaltungen v     -- v wie _v_eranstaltungen
        INNER JOIN termine t       -- t wie _t_ermine
        ON v.id = t.vid

          
        Danke für diesen Hinweis.  
          
        Der Join funktioniert ja tadellos, nur habe ich noch ein Problem bei der Ausgabe.  
          
        Noch mal ein Beispiel:  
          
        Tabelle Termine:  
        id  vid    beginn       ende  
        1 | 1  | 2005-10-05  |  2005-10-09  
        2 | 1  | 2005-11-05  |  2005-11-09  
        3 | 1  | 2005-12-05  |  2005-12-09  
          
          
        meine bisherige Ausgabe war immer:  
          
        Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)  
        von: 2005-10-05 bis: 2005-10-09  
          
        Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)  
        von: 2005-11-05 bis: 2005-11-09  
          
        Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)  
        von: 2005-12-05 bis: 2005-12-09  
          
          
        das Ziel ist aber:  
          
        Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)  
        von: 2005-10-05 bis: 2005-10-09  
        von: 2005-11-05 bis: 2005-11-09  
        von: 2005-12-05 bis: 2005-12-09  
          
          
        d.h. wohl, ich bräuchte 2 verschachtelte sql abfragen.  
          
        ich such mal im Forum danach.  
          
        Danke  
        Gruß Kim
        
        1. Hallo Kim,

          meine bisherige Ausgabe war immer:

          Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)
          von: 2005-10-05 bis: 2005-10-09
          Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)
          von: 2005-11-05 bis: 2005-11-09
          Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)
          von: 2005-12-05 bis: 2005-12-09

          das Ziel ist aber:

          Überschrift zur Veranstaltung mit id=1 (über vid verknüpft)
          von: 2005-10-05 bis: 2005-10-09
          von: 2005-11-05 bis: 2005-11-09
          von: 2005-12-05 bis: 2005-12-09

          d.h. wohl, ich bräuchte 2 verschachtelte sql abfragen.

          nein, das geht über Standard-SQL hinaus. Normalerweise machst Du so etwas in der Anwendung (also nicht in SQL). Du gibst einmal die Überschrift aus, dann die zugehörigen Zeilen. Als Suchbegriff dürfte Dir "Gruppenwechsel" weiterhelfen.

          Wenn Du alle Verstaltungen, sortiert nach der id (nicht besonders gutes Sortierkriterium), untereinander ausgeben lassen willst, innerhalb einer Veranstaltung jeweils nach dem Beginn der Veranstaltung, verwende die ORDER-BY-Klausel:

            
          SELECT  
            ueberschrift,  
            beginn  
            ende  
          FROM veranstaltungen v     -- v wie _v_eranstaltungen  
          INNER JOIN termine t       -- t wie _t_ermine  
          ON v.id = t.vid  
          ORDER BY v.id, beginn      -- Standardsortierung ist aufsteigend  
          
          

          Bei der Ausgabe gehst Du in etwa wie folgt vor:

          Gemerkte Überschrift = leere Zeichenkette
          Solange es Zeilen in der Ergebnismenge gibt
              Nimm die nächste Zeile
              Lese die Überschrift
              Wenn es eine neue Überschrift ist
                  Merke die Überschrift
                  Gebe die Überschrift aus
              Ende Wenn
              Gebe den Termin aus
          Ende Solange

          Freundliche Grüße

          Vinzenz

          1. Danke nochmal für deine tatkräftige Unterstützung!

            Bei der Ausgabe gehst Du in etwa wie folgt vor:

            Gemerkte Überschrift = leere Zeichenkette
            Solange es Zeilen in der Ergebnismenge gibt
                Nimm die nächste Zeile
                Lese die Überschrift
                Wenn es eine neue Überschrift ist
                    Merke die Überschrift
                    Gebe die Überschrift aus
                Ende Wenn
                Gebe den Termin aus
            Ende Solange

            Anhand deiner Beschreibung habe ich das umsetzen können. Danke.
            Es sieht wie folgt aus:

              
            $c_headline ="";  
            $o_headline ="";  
              
            while($row = mysql_fetch_assoc($result)) {  
                $c_headline = $row['headline'];      // _c_ für current  
                if($o_headline != $c_headline) {     // _o_ für old  
                    echo "<h3>".htmlentities($row['headline'])."</h3>";  
                    $o_headline = $c_headline;  
              
                }  
              
                echo $row['beginn']." - ".$row['ende']."<br/>";  
            }  
            
            

            Aber: bei der Strukturierung (HTML) habe ich Probleme.

            Ich möchte gern folgendes Grundgerüst (innerhalb von while):

              
              
            <!-- $o_headline != $c_headline START -->  
            <li>  
              <h3>Headline</h3>  
              <ul>  
            <!-- $o_headline != $c_headline ENDE -->  
              
                 <li>Termin 1</li>  
                 <li>Termin 2</li>  
                 ...  
                 <li>Termin 8</li>  
              
              </ul>  
            </li>  
              
            
            

            Mein Problem sind die letzten 2 Zeilen.
            Wie bekomme ich es hin, das er vor der nächsten (neuen) Überschrift
            den Listenpunkt und die letzte Terminliste schließt?

            Gruß
            Kim N.

            1. Hallo Kim,

              Du hast schon viel hinbekommen, mit der Erweiterung unten solltest Du den Rest auch noch hinbekommen.

              Ich möchte gern folgendes Grundgerüst (innerhalb von while):

              [code lang=html]

              <!-- $o_headline != $c_headline START -->
              <li>
                <h3>Headline</h3>
                <ul>
              <!-- $o_headline != $c_headline ENDE -->

              <li>Termin 1</li>
                   <li>Termin 2</li>
                   ...
                   <li>Termin 8</li>

              Mein Problem sind die letzten 2 Zeilen.
              Wie bekomme ich es hin, das er vor der nächsten (neuen) Überschrift
              den Listenpunkt und die letzte Terminliste schließt?

              Bei der ersten Überschrift darfst Du

              </ul>
              </li>

              nicht ausgeben, bei allen anderen gibst Du dies _vor_ der Überschrift aus. Nach Abarbeitung der Schleife beendest Du die innere Liste, schliesst den Listenpunkt der äußeren Liste und beendest die Liste:

              Gemerkte Überschrift = leere Zeichenkette
              Erste Überschrift = wahr

              Beginne die äußere Liste
              Solange es Zeilen in der Ergebnismenge gibt
                   Nimm die nächste Zeile
                   Lese die Überschrift
                   Wenn es eine neue Überschrift ist
                       Wenn es nicht die erste Überschrift ist
                           Beende die Liste der Termine
                           Schliesse den Listenpunkt
                       Sonst
                           Erste Überschrift = Falsch
                       Ende Wenn
                       Merke die Überschrift
                       Gebe die Überschrift aus
                   Ende Wenn
                   Gebe den Termin aus
              Ende Solange

              Beende die Liste der Termine
              Schliesse den Listenpunkt
              Schliesse die äußere Liste

              Freundliche Grüße

              Vinzenz