MySQL - Strucktur der Abfrage / While-Schleife

Hi ich zerbreche mir seit Stunden den Kopf ob die Abfrage so laufen darf.,
Und komme immer wieder zu dem Ergebnis. Ja… so muss das richtig sein.
Ich habe Zwei Tabellen: hoerspiele und hoerspiele_tracks ich verbinde beide mit einem Feld CDID über LEFT JOIN wie ich es hier gelernt habe.
CDID ist in hoerspiel ein index mit auto_increment und in beiden int(2) um zweistellige Werte ausgeben zu können.
Da ich dies mal nur eine CD pro Seite mit $_GET[‚SQL‘] aufrufe brauche ich (denke ich) also nur für die Tracks eine Schleife. Der Code sieht (auszugsweise) also so aus:

$ergebnis = mysql_query("SELECT * FROM hoerspiele_tracks s LEFT JOIN hoerspiele st USING(CDID) WHERE url ='" . mysql_real_escape_string($_GET['SQL']) . "' ");  // verbinde beide Tabellen 
($row = mysql_fetch_object($ergebnis));   // lese Daten 

Daten aus der Tabelle hoerspiele


           echo' Titel: ', $row->CD_Titel, ' <br />
                  
                            ', $row->Autor, ' <br />
                          ', $row->Verlag, ' <br />


 while($rowtrack = mysql_fetch_object($ergebnis));   // lese Daten aus Tabelle hoerspiele_tracks

 {                  echo '[TR]
                  [TD]t',$rowtrack->Track,'[/TD]
                  [TD]tt',$rowtrack->Track_Titel,'[/TD]
                  [TD]l',$rowtrack->Laenge,'[/TD]
                  [TD]s',$rowtrack->Sprecher,'[/TD]
                  [TD]'; 

                  if ($rowtrack->Track_Sternchen >0 )        // für 0 bild von Daumen runter einfügen / auch bei Büchern 
                       { 
                       echo'
                        $rowtrack->Track_Sternchen, ' Sterne"  />'; 
                       }  
                      else 
                       {
                        echo' ....';  
                         };                          // Track_Sternchen Ende
                  echo'[/TD]
                  [/TR]
'; };  

…Daten aus Tabelle hoerspiele…

Ich habe keine Fehlermeldung.
Die Daten aus hoerspiel werden richtig ausgegeben. Doch die aus hoerspiel_track fehlen.
Die Strucktur der Abfrage (also das die while-schleife nur für die Tracks da ist) muss doch so OK sein. Oder Täusche ich mich?
Ich hatte es zu erst mit einem Marker probiert. Bis mir einfiel… das ich ja nur die tracks mehrfach abfragen muss.

------------------ UpDate: mit der Strucktur meine ich folgendes: in Zeile

1: $ergebnis = mysql_query(„SELECT * FROM hoerspiele_tracks s LEFT JOIN hoerspiele st USING(CDID) WHERE url ='“ . mysql_real_escape_string($_GET[‚SQL‘]) . "’ "); // verbinde beide Tabellen
2: ($row = mysql_fetch_object($ergebnis)); // lese Daten

es folgen Daten aus Tabelle hoerspiel

50: while($rowtrack = mysql_fetch_object($ergebnis));
{

es werden nun die Zeilen 51 bis 70 so lange abgearbeitet bis kein Track mit der gleichen CDID vorhanden ist

70: }

weitere Daten der CD

80: ?>

Und wozu soll das gut sein?

Schema:

[code]-- phpMyAdmin SQL Dump
– version 3.4.5deb1
phpMyAdmin

– Host: localhost
– Generation Time: Dec 20, 2011 at 03:07 PM
– Server version: 5.1.58
– PHP Version: 5.3.6-13ubuntu3.3

SET SQL_MODE=„NO_AUTO_VALUE_ON_ZERO“;
SET time_zone = „+00:00“;


– Database: industriemeister



– Table structure for table hoerspiele

CREATE TABLE IF NOT EXISTS hoerspiele (
CDID int(11) NOT NULL AUTO_INCREMENT,
CD_Titel varchar(255) NOT NULL,
Autor varchar(255) NOT NULL,
Verlag varchar(255) NOT NULL,
url varchar(255) NOT NULL,
PRIMARY KEY (CDID),
KEY url (url)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;


– Dumping data for table hoerspiele

INSERT INTO hoerspiele (CDID, CD_Titel, Autor, Verlag, url) VALUES
(1, ‚Der kleine Hund‘, ‚Thomas Mustermann‘, ‚Hörbuchverlag‘, ‚der-kleine-hund‘),
(2, ‚Struppis großes Abenteuer‘, ‚Susanne Sorglos‘, ‚DHV Kids‘, ‚struppis-großes-abenteuer‘);



– Table structure for table hoerspiele_tracks

CREATE TABLE IF NOT EXISTS hoerspiele_tracks (
id int(11) NOT NULL AUTO_INCREMENT,
CDID int(11) NOT NULL,
Track int(11) NOT NULL,
Track_Titel varchar(255) NOT NULL,
Laenge int(11) NOT NULL,
Sprecher varchar(255) NOT NULL,
Track_Sternchen int(11) NOT NULL,
PRIMARY KEY (id),
KEY CDID (CDID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;


– Dumping data for table hoerspiele_tracks

INSERT INTO hoerspiele_tracks (id, CDID, Track, Track_Titel, Laenge, Sprecher, Track_Sternchen) VALUES
(1, 1, 1, ‚Hallo, da bin ich!‘, 726, ‚T. Langhand, P. Kurzbaum‘, 2),
(2, 1, 2, ‚Der vergessene Mantel‘, 579, ‚T. Langhand, P. Kurzbaum‘, 1),
(3, 1, 3, ‚Alfred ist da‘, 412, ‚T. Langhand, P. Kurzbaum, A. Mengel‘, 0),
(4, 2, 1, ‚Teil 1‘, 1456, ‚N. Nielsen, C. Larsen‘, 1),
(6, 2, 2, ‚Teil 2‘, 1502, ‚N. Nielsen, C. Larsen‘, 1);
[/code]

PHP:

[php]<?php

error_reporting(-1);
ini_set(‚display_errors‘, 1);

$_GET[‚SQL‘] = ‚der-kleine-hund‘;

/**
*

  • @param resource $dbh

  • @param string $url

  • @return resource
    */
    function getTracksByUrl($dbh, $url)
    {
    $entries = array();

    $q = "
    SELECT
    *
    FROM
    hoerspiele_tracks AS s
    LEFT JOIN
    hoerspiele AS st
    ON
    s.CDID = st.CDID
    WHERE
    st.url =‚" . $url . "‘
    ";

    $result = mysql_query($q, $dbh);

    if ($result === false) {
    throw new Exception(mysql_error($dbh));
    }

    while ($row = mysql_fetch_object($result)) {
    $entries = $row;
    }

    return $entries;
    }

$dbh = mysql_connect(‚localhost‘, ‚username‘, ‚password‘);
mysql_set_charset(‚utf8‘, $dbh);
mysql_select_db(‚industriemeister‘, $dbh);

$entries = getTracksByUrl($dbh, $_GET[‚SQL‘]);

foreach ($entries as $entry) {
foreach ($entry as $key => $value) {
printf(„% 20s : %s\n“, $key, $value);
}
echo „\n“;
}
[/php]

Ausgabe:

[code] id : 1
CDID : 1
Track : 1
Track_Titel : Hallo, da bin ich!
Laenge : 726
Sprecher : T. Langhand, P. Kurzbaum
Track_Sternchen : 2
CD_Titel : Der kleine Hund
Autor : Thomas Mustermann
Verlag : Hörbuchverlag
url : der-kleine-hund

              id : 2
            CDID : 1
           Track : 2
     Track_Titel : Der vergessene Mantel
          Laenge : 579
        Sprecher : T. Langhand, P. Kurzbaum
 Track_Sternchen : 1
        CD_Titel : Der kleine Hund
           Autor : Thomas Mustermann
          Verlag : Hörbuchverlag
             url : der-kleine-hund

              id : 3
            CDID : 1
           Track : 3
     Track_Titel : Alfred ist da
          Laenge : 412
        Sprecher : T. Langhand, P. Kurzbaum, A. Mengel
 Track_Sternchen : 0
        CD_Titel : Der kleine Hund
           Autor : Thomas Mustermann
          Verlag : Hörbuchverlag
             url : der-kleine-hund

[/code]

Deshalb hatte ich es mit der While-Schleife nur um hoerspiele_tracks probiert.
Wenn ich die While-Schleife um alles setzte wird ja so wie in der Ausgabe jedes mal alles aufgerufen.
So stelle ich mir das nicht vor.
So dachte ich mir das Ergebnis… deshalb mein Versuch.

Mustertitel
Mustermann
Leihdoch

Trackliste:
Track - Titel - Länge - Wertung
1 - Muster - …
2 - Test - …

Coverbild
Datum Online

CD Titel, Autor und Verlag sind nur an die CD nicht an die Tracks gebunden.
Ich habe kürzlich erfahren das man nur dann eine Index also Primarykey einzetzten soll wenn es notwenig ist.
Deshalb frage ich mich auch warum ich in der Track-Tabelle überhaupt einen setzen soll.

Wenn ich die While-Schleife um alles herum setzte dann wäre das wie in der Version die ich zuvor (nicht gepostet) versucht habe. Dort habe ich mit Markern gearbeitet.

Wenn du einzelne Tracks gezielt auswählen (identifizieren) möchtest, solltest du das tun.

[php]<?php

error_reporting(-1);
ini_set(‚display_errors‘, 1);

header(‚Content-Type: text/html; charset=UTF-8‘);

/**
*

  • @param string $s
  • @return string
    */
    function escape($s)
    {
    return htmlspecialchars($s, ENT_QUOTES, ‚UTF-8‘);
    }

/**
*

  • @param int $seconds

  • @return string
    */
    function secondsToHms($seconds)
    {
    $hmsString = ‚‘;

    if ($seconds >= 3600) {
    $hmsString .= (int) floor($seconds / 3600) . ‚:‘;
    $seconds -= (int) floor($seconds / 3600) * 3600;
    }

    if ($seconds >= 60) {
    if ($hmsString !== ‚‘) {
    $hmsString .= sprintf(‚%02s‘, (int) floor($seconds / 60)) . ‚:‘;
    } else {
    $hmsString .= (int) floor($seconds / 60) . ‚:‘;
    }
    $seconds -= (int) floor($seconds / 60) * 60;
    } else {
    if ($hmsString !== ‚‘) {
    $hmsString .= ‚00:‘;
    } else {
    $hmsString .= ‚0:‘;
    }
    }

    $hmsString .= sprintf(‚%02s‘, $seconds);

    return $hmsString;
    }

/**
*

  • @param int $rating

  • @return string
    */
    function visualizeRating($rating)
    {
    $output = ‚‘;

    if ($rating === 0) {
    $output = ‚-‘;
    } else {
    $output .= str_repeat(„\xE2\x98\x85“, $rating);
    }

    return $output;
    }

/**
*

  • @param stdClass $entity

  • @return string
    */
    function debugEntity(stdClass $entity)
    {
    $output = ‚‘;

    foreach ($entity as $key => $value) {
    $output .= sprintf(„% 20s : %s\n“, $key, $value);
    }

    return $output;
    }

/**
*

  • @param resource $dbh

  • @param string $url

  • @return stdClass

  • @throws Exception
    */
    function getAlbumByUrl($dbh, $url)
    {
    $album = null;

    $q = "
    SELECT
    *
    FROM
    hoerspiele
    WHERE
    url =‚" . mysql_real_escape_string($url, $dbh) . "‘
    LIMIT
    0,1
    ";

    $result = mysql_query($q, $dbh);

    if ($result === false) {
    throw new Exception(mysql_error($dbh));
    }

    $album = mysql_fetch_object($result);

    return $album;
    }

/**
*

  • @param resource $dbh

  • @return array

  • @throws Exception
    */
    function getAlbums($dbh)
    {
    $albums = array();

    $q = "
    SELECT
    *
    FROM
    hoerspiele
    ORDER BY
    CD_Titel ASC
    ";

    $result = mysql_query($q, $dbh);

    if ($result === false) {
    throw new Exception(mysql_error($dbh));
    }

    while ($row = mysql_fetch_object($result)) {
    $albums = $row;
    }

    return $albums;
    }

/**
*

  • @param resource $dbh

  • @param stdClass $album

  • @return resource
    */
    function getTracksByAlbum($dbh, stdClass $album)
    {
    $tracks = array();

    $q = "
    SELECT
    *
    FROM
    hoerspiele_tracks
    WHERE
    CDID =‚" . mysql_real_escape_string($album->CDID, $dbh) . "‘
    ORDER BY
    Track ASC
    ";

    $result = mysql_query($q, $dbh);

    if ($result === false) {
    throw new Exception(mysql_error($dbh));
    }

    while ($row = mysql_fetch_object($result)) {
    $tracks = $row;
    }

    return $tracks;
    }

// Verbindung aufbauen

$dbh = mysql_connect(‚localhost‘, ‚username‘, ‚password‘);
mysql_set_charset(‚utf8‘, $dbh);
mysql_select_db(‚industriemeister‘, $dbh);

// Alle Alben holen und Tracks ergänzen

$albums = getAlbums($dbh);

// Diese Schleife ist ineffizient und sollte besser als JOIN geschrieben werden.
// Entsprechende Mapping-Algorithmen zu schreiben, ist aber kein Vergnügen.
// Dafür gibt es fertige ORM-Tools wie Doctrine
foreach ($albums as $album) {
$album->Tracks = getTracksByAlbum($dbh, $album);
}

// Ausgabe

?>

Sammlung

    <?php foreach ($albums as $album) : ?>
  • <h1><?php echo escape($album->CD_Titel); ?></h1>
    
    <p><?php echo escape($album->Autor); ?> (<?php echo escape($album->Verlag); ?>)</p>
    
    <h2>Tracks</h2>
    
    <table>
        <thead>
        <tr>
            <th>#</th>
            <th>Titel</th>
            <th>Länge</th>
            <th>Bewertung</th>
        </tr>
        </thead>
    
        <tbody>
    
        <?php foreach ($album->Tracks as $track) : ?>
    
        <tr>
            <td><?php echo escape($track->Track); ?></td>
            <td><?php echo escape($track->Track_Titel); ?></td>
            <td><?php echo escape(secondsToHms((int) $track->Laenge)); ?></td>
            <td><?php echo escape(visualizeRating((int) $track->Track_Sternchen)); ?></td>
        </tr>
    
        </tbody>
    
        <?php endforeach; ?>
    </table>
    
  • <?php endforeach; ?>
[/php]

Mir ist nicht ganz klar wozu die ganzen funktionen dienen.
Ich habe in einer anderen Version die while-schleife mal auskommentiert. Dann wird das Ergebnis in der Anlage ausgegeben. Die Daten der cd mit dem ersten Track. Das ist mir soweit auch klar, weil ja nur einmal abgefragt wird.
Jedoch nehme ich die Kommentierung vor der While-Schleife (siehe Code) weg. Dann werden überhaupt keine Daten mehr ausgegeben.

Mein Ziel ist jedoch das alle Tracks in der Liste aufgezählt werden.

[CODE] $ergebnis = mysql_query(„SELECT * FROM hoerspiele_tracks s LEFT JOIN hoerspiele st USING(CDID) WHERE url ='“ .mysql_real_escape_string($_GET[‚SQL‘]) . "’ ");

// while
($row = mysql_fetch_object($ergebnis));
// {

                                          //             for ($i = 1; $i <= 2; $i++) :  ;   // modulus fr IE


                                                            $class = '';     // Definiton class für Zeilenwechsel IE
                                                            if ($i == 0) {
                                                                $class = 'track-zeile1';
                                                            } else if ($i % 2 === 0) {
                                                                $class = 'track-ungerade';
                                                            } else {
                                                                $class = 'track-gerade';
                                                            };      //     endfor

     // H Ö R S P I E L E  haben mindestens eine Bewertung
     echo'
     <div class="lass">
             <div class="glowtext-medien">', $row->CD_Titel, '</div>
             <div class="ornament-l"></div>
                     <div class="titel-box">
                     <div class="glowtext_autor">', $row->Autor, '</div>
                     <div class="verlag">', $row->Verlag, '</div>
     </div>
             <div class="ornament-r"></div>

             <!-- Cover Vorn -->
             <div class="cover_left">    <!-- hintergrundfarbe #DCB8B8 width=203 height=285 -->
                     ', $row->Wetget_Code, '

     <!-- <img border="0" src="'.$LINK.'Images/Medien/offe_rechte.gif" width="203" /> -->

                     <div class="quelle">
                             Quelle Bild: amazonPartnerNet
                     </div>
             </div>  <!-- Cover Vorn ENDE -->

             <!-- Cover Hinten -->
             <div class="cover_right">';
             echo '<table class="tracktabelle">
                     <tr>
                     <th class="track_h">Track</th>
                     <th class="track_h">Titel</th>
                     <th class="track_h">Lange</th>
                     <th class="track_h">Sprecher</th>
                     <th class="track_h">Wertung</th>
                     </tr>';


             echo '<tr>
             <td>',$row->Track,'</td>
             <td>',$row->Track_Titel,'</td>
             <td>',$row->Laenge,'</td>
             <td>',$row->Sprecher,'</td>
             <td>';

             if ($row->Track_Sternchen >0 )        // für 0 bild von Daumen runter einfügen / auch bei Büchern
             {
             echo'
             <img src="'.$LINK.'Images/wertungsstern' ,$row->Track_Sternchen, '.gif" height="9" alt="' ,$row->Track_Sternchen, ' Sterne"  />';
             }
             else
             {
             echo' <img src="'.$LINK.'Images/unbewert.gif" height="9">';
             };
                     // Track_Sternchen Ende
             echo'</td>
             </tr>';

                                           $i++;       //  IE Modulus hochzählen  


     echo '
             </table> <!-- Tabelle ENDE -->

             </div>  <!-- Cover Hinten Ende -->
             <!-- Bewertung Begin -->
             <div class="cd-inhalt">
                     <div class="CD_Wertung">';

                             if ($row->NEU != 1)
                             {
                             echo' <img src="'.$LINK.'Images/kolibrie.gif" height="30" border="1" alt="neu" />';
                             };

                             echo'
                             <u>Gesammtwertung:</u></span>';

                             if ($row->Sternchen >0 )        // für 0 bild von Daumen runter einfügen / auch bei Büchern
                             {
                             echo'
                             <img src="'.$LINK.'Images/wertungsstern' ,$row->Sternchen, '.gif" height="9" alt="' ,$row->Sternchen, ' Sterne"  />';
                             }
                             else
                             {
                             echo' <img src="'.$LINK.'Images/unbewert.gif" height="9">';
                             };
                                   // GESAMTSternchen Ende

                            echo'
                            <span class="CD_Wertung_dat">Bewertet am ' ,strftime("%d. %B %Y", strtotime($row->Bewert_Datum)), '&nbsp;</span>';
                            // Datum Ende

                            echo'
                            </div> <!-- ende CD Wertung -->
                      </div>';
                             // ende CD Inhalt



     echo '</div>';

// }; // ende While[/CODE]

Du machst es uns sehr schwer dir zu helfen.

Warum versuchst du nicht erstmal dir nur die rohen Daten ausgeben zu lassen - ohne Bildchen ohne SchnickSchnack - so müssen wir uns (und du auch) mit grossen Codeblöcken abmühen, die wir gedanklich nachvollziehen müssen, was aber einer gewissen Komplexität mir schwer fällt und ich auch nicht unbedingt die Lust dazu habe, kostenlos komplexe Programmierungen hier im Forum zu machen.

Das verstehe ich. Ich habe das immer drin gelassen weil ich mit dem Aufbau der Seite angefangen habe. Und erst dann die Tabellen-Daten eingefügt habe. Erst recht die zwei verbunden.

So ich habe nun alles weggelassen was nicht direkt mit der Abfrage / Ergebnis zu tun hat.
Die drei Bilder die nun noch drin sind, sind Ergebnisse von if-schleifen die zur Abfrage gehören.

Das Problem der Datenausgabe ist das selbe wenn ich die Kommentierung vor der while-schleife wieder wegnehme.

[CODE]<?php
setlocale (LC_ALL, ‚de_DE@euro‘, ‚de_DE‘, ‚de‘, ‚ge‘);

// H Ö R S P I E L E
// if ($_GET[‚Art‘] == „hoerspiele“)
{
$ergebnis = mysql_query(„SELECT * FROM hoerspiele_tracks s LEFT JOIN hoerspiele st USING(CDID) WHERE url ='“ .mysql_real_escape_string($_GET[‚SQL‘]) . "’ ");

while($row = mysql_fetch_object($ergebnis));
{

     // H Ö R S P I E L E  haben mindestens eine Bewertung
     echo
              $row->CD_Titel,'<br />',

$row->Autor,‚
‘,$row->Verlag,‚
‘;

echo ‚traks‘, $row->Track, $row->Track_Titel, $row->Laenge, $row->Sprecher;

             if ($row->Track_Sternchen >0 )        // für 0 bild von Daumen runter einfügen / auch bei Büchern
             {
             echo'
             <img src="'.$LINK.'Images/wertungsstern' ,$row->Track_Sternchen, '.gif" height="9" alt="' ,$row->Track_Sternchen, ' Sterne"  />';
             }
             else
             {
             echo' <img src="'.$LINK.'Images/unbewert.gif" height="9">';
             };
                     // Track_Sternchen Ende

                           if ($row->NEU != 1)
                             {
                             echo'<br /> <img src="'.$LINK.'Images/kolibrie.gif" height="30" border="1" alt="neu" />';
                             };


                             echo'
                             <u>Gesammtwertung:</u>';

                             if ($row->Sternchen >0 )        // für 0 bild von Daumen runter einfügen / auch bei Büchern
                             {
                             echo'
                             <img src="'.$LINK.'Images/wertungsstern' ,$row->Sternchen, '.gif" height="9" alt="' ,$row->Sternchen, ' Sterne"  />';
                             }
                             else
                             {
                             echo' <img src="'.$LINK.'Images/unbewert.gif" height="9">';
                             };
                                   // GESAMTSternchen Ende

                            echo'
                          Bewertet am ' ,strftime("%d. %B %Y", strtotime($row->Bewert_Datum));

};
} // if Höerspiele

?>[/CODE]

UpDate----

Ein Check der Zeile SELECT * FROM hoerspiele_tracks s LEFT JOIN hoerspiele st USING(CDID) where url=„das_erste_mal“ gab alle erwarteten Tracks zurück
Daraus kann ich also folgern das der select richtig ist.

Ich verstehe nur nicht warum es mit while-schleife keine Ergebnisse gibt
und ohne while-schleife die CD-Daten + der Daten des ersten Tracks.
Auch mein Buch und was ich an deutschen Seiten dazu gelesen habe gibt mir dafür keine Antwort.
hat bei myadminsql ergeben das alle Tracks

Ich arbeite nun also mit der reduzierten Version.
Und stelle fest selbst wenn ich WHERE… rausnehme kommt KEIN Ergebnis (keine Daten) mehr.
Eigentlich müsste doch spätestens dann alles was in den Tabellen eingetragen ist als Kreuztabelle vorkommen., oder nicht?

Ein Check der Zeile SELECT * FROM hoerspiele_tracks s LEFT JOIN hoerspiele st USING(CDID) where url=„das_erste_mal“ gab alle erwarteten Tracks und CD-Daten mit dem markieren Verknüpfungsfeld zurück
Daraus kann ich also folgern das der select richtig ist.

Ich verstehe nur nicht warum es mit while-schleife keine Ergebnisse gibt
und ohne while-schleife die CD-Daten + der Daten des ersten Tracks.
Auch mein Buch und was ich an deutschen Seiten dazu gelesen habe gibt mir dafür keine Antwort.
hat bei myadminsql ergeben das alle Tracks

Kennt jemand das Buch MySQL 5 (bhv Einsteigersemin​ar)?
Denn in meinem aktuellen Buch PHP5.3 & MySQL5.1 steht nicht so viel über SQL und die Verbindung zu PHP. Ansonsten bin ich damit (was PHP angeht) sehr zufrieden

---- Lösung gefunden —
Frage nach Buch noch aktuell