Kermit: Frage zur MySql Abfrage

Hallo,
arbeite mit PHP und MySql (weiß jetzt nicht die aktuelle Versions Nr müßte aber irgendwas 4 sein...)
Habe in meiner Datenbank u.a. eine Tabelle mit Alben, eine Tabelle mit Tracks eine Zuordnung der Tracks zu den Alben und eine Tabelle mit Lizenzrechten.
Ein Track auf einem Album kann eine unterschiedliche Lizenz haben als das gesamte Album.
t_album
id
album_nr
album_name
lizenz_id
etc...

t_track
id
track_name
lizenz_id
etc...

t_lizenz
id
lizenz_name

t_track_album
track_id
album_id
reihenfolge

select alb.id, alb.album_nr alb.album_name, alb.lizenz_id, t.id, t.track_name. t.lizenz_id, ta.reihenfolge from t_album alb, t_track t, t_track_album ta where ta.album_id=alb.id and tr.id=ta.track_id order by alb.id, ta.reihenfolge

Soweit so gut - nur möchte ich gerne, daß mir der Lizenzname ausgegeben wird und nicht nur die ID Nr, da ich aber sowohl für die Track Lizenz wie auch für die Album Lizenz per ID auf die Tabelle t_lizenz verweise, weiß ich nicht wie ich das richtig schreiben müßte, damit mir sowohl eine Spalte "Album Lizenz" wie auch eine Spalte "Track Lizenz" ausgegeben wird.

Dankbar für eine Antwort

Kermit

  1. echo $begrüßung;

    arbeite mit PHP und MySql (weiß jetzt nicht die aktuelle Versions Nr müßte aber irgendwas 4 sein...)

    Zwischen den MySQL-Versionen 4.0 und 4.1 liegen Welten. Andere 4er gibt es nicht.

    select alb.id, alb.album_nr alb.album_name, alb.lizenz_id, t.id, t.track_name. t.lizenz_id, ta.reihenfolge from t_album alb, t_track t, t_track_album ta where ta.album_id=alb.id and tr.id=ta.track_id order by alb.id, ta.reihenfolge

    Recht unübersichtlich notiert. Schriebst du die Schlüsselwörter in Großbuchstaben wäre es schon ein wenig leichter.

    SELECT
        alb.id, alb.album_nr alb.album_name, alb.lizenz_id,
        t.id, t.track_name. t.lizenz_id,
        ta.reihenfolge
      FROM
        t_album alb,
        t_track t,
        t_track_album ta
      WHERE ta.album_id=alb.id and tr.id=ta.track_id
      ORDER BY alb.id, ta.reihenfolge

    So notiert ist es schon fast nicht mehr zu toppen.

    Soweit so gut - nur möchte ich gerne, daß mir der Lizenzname ausgegeben wird und nicht nur die ID Nr, da ich aber sowohl für die Track Lizenz wie auch für die Album Lizenz per ID auf die Tabelle t_lizenz verweise, weiß ich nicht wie ich das richtig schreiben müßte, damit mir sowohl eine Spalte "Album Lizenz" wie auch eine Spalte "Track Lizenz" ausgegeben wird.

    Du hast ja schon (implizite) Joins verwendet. Du kannst da auch noch einen für die Lizenztabelle hinzufügen und mit dem Album verbinden. Und dann die Lizenztabelle noch ein zweites Mal (mit anderem Alias) joinen, diesmal aber mit der Tracktabelle verbinden. Schau dir auch mal die explizite Join-Syntax an, die ist in vielen Augen besser lesbar, weil sie die Join-Information an einer Stelle notiert und nicht auf FROM und WHERE aufteilt.

    An die Aufgabenstellung würde ich allerdings andere herangehen, dann bekommst du das Problem des doppelten Joins gar nicht. Bei einer Auflistung der Tracks würde ich nur die Track-Information abfragen. Die Album-Information da mit hineinzubringen ist ziemlich redundant, da sie ja für jeden Track gleich ist. Die Album-Information würde ich also mit einem eigenen Statement abfragen. Du kannst sie ja bei der Bildschirmausgabe immer noch mit den Tracks zusammenfügen. Oder du notierst sie einfach nur einmal und hast auch auf dem Bildschirm keine Redundanzen (und vielleicht auch eine kürzere, übersichtlichere Darstellung).

    echo "$verabschiedung $name";

    1. Hallo Dedlfix,
      erstamal danke.

      Du hast ja schon (implizite) Joins verwendet. Du kannst da auch noch einen für die Lizenztabelle hinzufügen und mit dem Album verbinden. Und dann die Lizenztabelle noch ein zweites Mal (mit anderem Alias) joinen, diesmal aber mit der Tracktabelle verbinden. Schau dir auch mal die explizite Join-Syntax an, die ist in vielen Augen besser lesbar, weil sie die Join-Information an einer Stelle notiert und nicht auf FROM und WHERE aufteilt.

      8-0  ?? Hmm, verstehe ich jetzt leider nicht. Mit den Join Statements stehe ich absolut auf dem Kriegsfuß - das habe ich bisher noch nie verstanden wie die Syntax aussehen muß (daher auch meine krude Abfragepraxis....)

      An die Aufgabenstellung würde ich allerdings andere herangehen, dann bekommst du das Problem des doppelten Joins gar nicht. Bei einer Auflistung der Tracks würde ich nur die Track-Information abfragen. Die Album-Information da mit hineinzubringen ist ziemlich redundant, da sie ja für jeden Track gleich ist. Die Album-Information würde ich also mit einem eigenen Statement abfragen. Du kannst sie ja bei der Bildschirmausgabe immer noch mit den Tracks zusammenfügen. Oder du notierst sie einfach nur einmal und hast auch auf dem Bildschirm keine Redundanzen (und vielleicht auch eine kürzere, übersichtlichere Darstellung).

      Die Redundanz ist in diesem speziellen Fall gewünscht bzw. gefordert sonst hätte ich das Problem gar nicht....
      Grüße

      1. echo $begrüßung;

        Mit den Join Statements stehe ich absolut auf dem Kriegsfuß - das habe ich bisher noch nie verstanden wie die Syntax aussehen muß (daher auch meine krude Abfragepraxis....)

        Dabei gibt es doch die beiden Artikel Einführung in Joins und Fortgeschrittene Jointechniken.

        Wenn du

        SELECT ...
          FROM a, b
          WHERE a.feld=b.feld AND a.feld=irgendwas

        notierst, hast du Tabelle a mit b verbunden über die Bedingung a.feld=b.feld. Das kannst du auch so notieren:

        SELECT ...
          FROM a
            JOIN b ON a.feld=b.feld
          WHERE a.feld=irgendwas

        Die Bedingung hinter ON sieht genauso aus wie hinter WHERE, nur dass sie nun direkt als zugehörig zum Join mit der Tabelle b sichtbar ist.

        a.feld=irgendwas dient zur Einschränkung der zu beachtenden Datensätze und ist kein Verknüpfungskriterium, weswegen es in der WHERE-Klausel verbleibt.

        Die Redundanz ist in diesem speziellen Fall gewünscht bzw. gefordert sonst hätte ich das Problem gar nicht....

        Du hast also die Tabellen track, album, track_album und lizenz und du möchtest alle Tracks haben

        FROM track

        dazu die Lizenz des Tracks

        JOIN lizenz AS track_lizenz ON track.lizenz_id = track_lizenz.id

        außerdem das Album, das über einer Verknüpfungstabelle mit den Tracks verbunden ist

        JOIN track_album ON track.id = track_album.track_id
            JOIN album ON track_album.album_id = album.id

        und die Lizenz des Albums

        JOIN lizenz AS album_lizenz ON album.lizenz_id = album_lizenz.id

        Die Tabelle lizenz wird also zweimal gejoint, ihr aber unterschiedliche Aliasnamen gegeben, damit die jeweils richtigen Werte zusammengebracht werden können und auch bei der Ausgabe der Felder im SELECT-Teil die richtige Lizenz angesprochen werden kann.

        Es kann auch notwendig sein, LEFT JOINs statt der (INNER) JOINs zu verwenden. Der Fall tritt ein, wenn zu einem Datensatz aus der links notierten Tabelle kein Datensatz aus der weiter rechts notierten Tabelle existiert (Tracks ohne Album, Tracks oder Alben ohne Lizenz). Der LEFT JOIN bringt dann auch diese Datensätze in der Ausgabe. Für Werte, die aus Feldern der rechten Tabelle kämen, würde in dem Fall NULL in der Ausgabe stehen.

        echo "$verabschiedung $name";