SQL Abfrage - Ausgabe in HTML Tabelle

CoverUnder

Mitglied
Hallo,

wieder einmal scheitert es an meiner theoretischen Planung... und würde mich sehr freuen, wenn mir jemand einen Tipp geben könnte - selbst wenn es nur ein Stichwort ist, ich freue mich über alles, was mir weiter hilft.

Folgendes:

Ich habe zwei Datenbanktabellen. Die eine nennt sich "Produkte" und die andere "Preise". In der Tabelle "Produkte" finden sich allerlei Informationen wie zb. Name, Bild und so weiter. In der Tabelle "Preise" hat jedes Produkt mindestens einen, meistens aber mehrere Einträge (Datensätze), da viele Produkte auch Staffelpreise haben.

Die Tabelle "Preise" enthält folgende Spalten:
Produkt-ID: Ist, denke ich, klar - damit der Preis einem Produkt zugeordnet werden kann
Anzahl: Die Anzahl definiert die Staffelpreise. Sprich: Steht bei Anzahl "1" - gilt der Preis wenn man ein Stück kauft. Steht bei Anzahl zb. "3" gilt der Preis ab einer Bestellmenge von drei Stück - dann wirds billiger.
Preis: Enthält den Preis für die jeweilige Anzahl

Nun hätte ich gerne via PHP eine Preisliste erzeugt, die mir allgemeine Produktinformationen ausliest und die Preise inklusive Staffelpreise.

Aktuell bin ich so weit, dass ich mittels HTML/PHP eine Tabelle ausgebe, die folgende Spalten hat (gekürzt & vereinfacht):

"ID - Foto - 1 - 2 - 3 - 4 - 5"

ID und Foto sind simpel - die lese ich einfach aus der Produkt-Tabelle aus. Das Problem liegt bei den Zahlen. Die Zahlen kommen direkt aus der Tabelle "Preise" aus dem Feld "Anzahl". Das mache ich so:

PHP:
$sql = "SELECT DISTINCT anzahl FROM preise ORDER BY anzahl ASC";

Nun kommen wir zum eigentlichen Problem: Die HTML-Tabelle mit Inhalten füllen. Das da oben sind ja nur die Überschriften. Nun muss aber der Inhalt hinein. Die Sache ist die, dass ein Produkt zum Beispiel Einträge für alle Spalten hat - sprich, Preise für Anzahl 1, Anzahl 2, 3, 4 und 5. Andere Produkte wiederum haben aber nur Preise für 1 und 5 zum Beispiel.

So sollte die Tabelle dann theoretisch aussehen:

Code:
ID - Foto - 1 - 2 - 3 - 4 - 5
3 - Img - 9€ - 8€ - 7€ - 6€ - 5€
4 - Img - 3€ - // - 2€ - // - //

Sprich: Irgendwie muss das Script wissen, in welcher HTML-Tabellenspalte es den jeweiligen Preis ausgeben muss. Dass der Preis für 3 Stück auch in die Spalte "3" kommt. Die Werte müssen in der HTML Tabelle sozusagen sortiert werden.
Aktuell versuche ich die Sache theoretisch zu durchdenken, bevor ich weiter daran schreibe, aber leider stehe ich schon seit einer gefühlten halben Ewigkeit total auf dem Schlauch.

Ich hoffe meine Erklärung war nun einigermaßen nachvollziehbar. Sonst bitte melden, dann versuche ich es noch einmal anders zu formulieren.

Ein herzliches Danke schonmal!
 
Zuletzt bearbeitet:
Sollte es für 1 und 5 nicht so aussehen? (nur zum Verständnis, ich glaube Du hast Dich da vertippt).
Code:
ID - Foto - 1 - 2 - 3 - 4 - 5
3 - Img - 9€ - 8€ - 7€ - 6€ - 5€
4 - Img - 3€ - // - // - // - 5€

Soweit ich das jetzt nachvollzogen hab, sollte das in etwa so klappen:

PHP:
$result = mysql_query('SELECT DISTINCT...'); 
$last = 1;
while( $row = mysql_fetch_assoc($result) ){
  while( $row['anzahl'] < $last ){
    echo '<td>LeeresFeld</td>';
  }
  echo '<td>'.$row['Preis'].'</td>';
  $last = $row['anzahl']+1;
}
 
Ein wenig schonglieren mit Arrays *g*

PHP:
//Daten simulieren
$staffeln = array(1,2,3,4,5);
//Daten wie sie etwa aus der DB kommen (das resultat von mysql_fetch_assoc direkt in ein Array speichern)
$data[] = array('pid' => 3, 'anzahl' => 1, 'preis' => 9);
$data[] = array('pid' => 3, 'anzahl' => 2, 'preis' => 8);
$data[] = array('pid' => 3, 'anzahl' => 3, 'preis' => 7);
$data[] = array('pid' => 3, 'anzahl' => 4, 'preis' => 6);
$data[] = array('pid' => 3, 'anzahl' => 5, 'preis' => 5);
$data[] = array('pid' => 4, 'anzahl' => 1, 'preis' => 3);
$data[] = array('pid' => 4, 'anzahl' => 3, 'preis' => 2);

/**
 * gewünschte Form
 * array(3 => array('pid' => 3, 's1' => 9, 's2' => 8, 's3'=> 7, 's4'=> 6, 's5'=>5),
 *       4 => array('pid' => 4, 's1' => 3, 's2' => NULL, 's3'=> 2, 's4'=> NULL, 's5'=>NULL))
 */

//Alle produkt-Ids ermitteln. Funktion array_extract_sub_item ist weiter unten aufgeführt
$pids = array_extract_sub_item($data, 'pid');

//Das Gitter zusammenstellen
foreach($pids as $pid){
    $result[$pid]['pid'] = $pid;
    foreach($staffeln as $staffel){
        $result[$pid]["s{$staffel}"] = NULL;   
    }    
}

//Das Gitter abfüllen
foreach($data as $item){
    $result[$item['pid']]["s{$item['anzahl']}"] = $item['preis'];
}

print_r($result);


/**
 * Extrahieren ein Subitem aus einem mehrstufigen Array. Der Schlüssel wird beibehalten
 * http://wiki.yaslaw.info/wikka/PhpArrayExtractSubItem
 * @param   Array<Key => Array<Node>>   Ein mehrstufiger Array
 * @param   String                      Schlüssel des zu extrahierenden Item
 * @return  Array<Key => Node>
 */
function array_extract_sub_item($array, $key){
    foreach($array as $index => $item) $retArray[$index] = $item[$key];
    return $retArray;
}
 
Zuerst vielen lieben Dank an euch für eure Hilfe! Den Ansatz von timestamp habe ich bereits probiert, nur leider werden da einfach alle tds der Reihe nach gefüllt - ohne ein leeres td zu erzeugen. Sprich, wenn es eigentlich so aussehen sollte:
Code:
ID - Foto - 1 - 2 - 3 - 4 - 5
3 - Img - 9€ - 8€ - 7€ - 6€ - 5€
4 - Img - 3€ - // - // - // - 5€

sieht es trotzdem so aus:
Code:
ID - Foto - 1 - 2 - 3 - 4 - 5
3 - Img - 9€ - 8€ - 7€ - 6€ - 5€
4 - Img - 3€ - 5€ - // - // - //

Die Lösungs von Yaslaw habe ich noch nicht probiert, die versuche ich gerade nachzuvollziehen und zu verstehen... :)
Du schreibst: "das resultat von mysql_fetch_assoc direkt in ein Array speichern" - erzeugt mysql_fetch_assoc nicht ein Array? Oder bin ich da falsch informiert? Arrays und SQL Join sind meine absoluten PHP-Schwächen, leider. Da kann ich mir noch so viele Tutorials durchlesen, so richtig verstehen tu ich es trotzdem nicht, also entschuldige bitte, wenn ich mit etwas blöden Fragen komme. Das heißt nicht, dass ich mich nicht bemühe
 
Jepp, mysql_fetch_assoc() generiert ein Array (Eine Zeile mit mehreren Feldern).
Dieses musst du wieder in ein Array packen. Das eibt einen 2-Dimensionalen Array der einer Tabelle entspricht.

Also, das Resultat entspricht in meinem Beispiel einer Zeile $data[]

PHP:
//So erstellst du ein $data das analog zu dem in meinem Beispiel ist (ggf. heissen die Keys anderst - je nachdem wie sie in deinem SQL heissen)
while($row = mysql_fetch_assoc($result)){
    $data[] = $row;
}
 
Ah, Danke! Jetzt wird mir einiges klar...
Gut, ich habe dein Script jetzt mal angepasst.

$staffeln kann ich nicht so erzeugen wie du, sondern muss es aus der Datenbank auslesen. Das habe ich so gemacht:

PHP:
$anzahl_sql = mysql_db_query("$mysqldb", "SELECT DISTINCT anzahl FROM tabelle");
while ($row = mysql_fetch_assoc($res)) {

...


$staffeln[] = $row;

}

Dann habe ich den Anfang deines Scripts so umgesetzt:

PHP:
$result = mysql_query("SELECT DISTINCT anzahl, preis, pid FROM tabelle WHERE pid = $pid ORDER BY anzahl ASC");

while( $row = mysql_fetch_assoc($result) ){

$data[] = $row;

}

Und anschließend den Rest kopiert:

PHP:
//Alle produkt-Ids ermitteln. Funktion array_extract_sub_item ist weiter unten aufgeführt
$pids = array_extract_sub_item($data, 'pid');
 
//Das Gitter zusammenstellen
foreach($pids as $pid){
    $result[$pid]['pid'] = $pid;
    foreach($staffeln as $staffel){
        $result[$pid]["s{$staffel}"] = NULL;   
    }    
}
 
//Das Gitter abfüllen
foreach($data as $item){
    $result[$item['pid']]["s{$item['anzahl']}"] = $item['preis'];
}
 
print_r($result);
 
 
/**
 * Extrahieren ein Subitem aus einem mehrstufigen Array. Der Schlüssel wird beibehalten
 * http://wiki.yaslaw.info/wikka/PhpArrayExtractSubItem
 * @param   Array<Key => Array<Node>>   Ein mehrstufiger Array
 * @param   String                      Schlüssel des zu extrahierenden Item
 * @return  Array<Key => Node>
 */
function array_extract_sub_item($array, $key){
    foreach($array as $index => $item) $retArray[$index] = $item[$key];
    return $retArray;
}

Als Fehlermeldung kommt:

Code:
Fatal error: Call to undefined function array_extract_sub_item()


edit: Aaaah, jetzt ist der Groschen gefallen, glaube ich?! Du sortierst nach der Produktid, was aber eigentlich nicht nötig ist, da ich das schon in der Abfrage drin hab... Kann der Fehler damit zusammenhängen?
 
item: Die Staffeln sind ein 1-Dimensionaler array. Ergo nicht die ganze Gruppe übergeben sondern nur den Wert
PHP:
$anzahl_sql = mysql_db_query("$mysqldb", "SELECT DISTINCT anzahl FROM tabelle");
while ($row = mysql_fetch_assoc($res)) {
    $staffeln[] = $row['anzahl'];
}

item: Nope, ich sortiere nicht nach der pid. Ich verwedne sie als Index der neuen Zeilen.
Aber was ich grad sehe, auf die pids sollten wir noch ein array_unique() machen
PHP:
//Alle produkt-Ids ermitteln. Funktion array_extract_sub_item ist weiter unten aufgeführt
$pids = array_extract_sub_item($data, 'pid');
$pids = array_unique($pids);
doch das löst unser Problem noch nicht.

Ist dieser Ablauf innerhalb einer anderer Funktion oder einer Klasse?

Ansonsten versuch mal
Verschiebe die Funktionsdefinition vor den Funktionsaufruf.

Wenn das nicht klappt, spühl die Funktion und wir extrahieren direkt
PHP:
$pids = array;
foreach($data as $index => $item) $pids [$index] = $item['pid'];
$pids = array_unique($pids);
 
Wieder einmal muss ich dafür entschuldigen, dass ich mich nicht gleich wieder gemeldet habe. Wie schon in anderen Threads erwähnt, bin ich momentan leider sehr stark eingespannt. Das tut mir Leid. Ich hoffe euch vergeht deshalb nicht die Lust mir zu helfen...


Okay...
Also ich habe die Funktion jetzt entfernt und stattdessen deinen Codeschnipsel verwendet.

Das Ergebnis:

PHP:
$sql = "SELECT DISTINCT anzahl FROM tabelle ORDER BY anzahl ASC";
$res = mysql_db_query($mysqldb, $sql, $mysql);

      while ($row = mysql_fetch_assoc($res)) {

         $anzahl = $row['anzahl'];
         
         ...
         
         $staffeln[] = $anzahl;
         
         }

Dann wie schon im vorherigen Post der Anfang:

PHP:
$result = mysql_query("SELECT DISTINCT anzahl, preis, pid FROM tabelle WHERE pid = $pid ORDER BY anzahl ASC");

while( $row = mysql_fetch_assoc($result) ){

$data[] = $row;

}

Dann habe ich die Funktion entfernt und nun steht das hier:

PHP:
$pids = array;
foreach($data as $index => $item) $pids [$index] = $item['pid'];
$pids = array_unique($pids);  
 
//Das Gitter zusammenstellen
foreach($pids as $pid){
    $result[$pid]['pid'] = $pid;
    foreach($staffeln as $staffel){
        $result[$pid]["s{$staffel}"] = NULL;   
    }    
}
 
//Das Gitter abfüllen
foreach($data as $item){
    $result[$item['pid']]["s{$item['anzahl']}"] = $item['preis'];
}
 
print_r($result);

Als Meldung kommt

Code:
Parse error: syntax error, unexpected ';', expecting '(' in ... on line 195

Das ist diese Zeile:

Code:
$pids = array;

Und um ehrlich zu sein... ich werde wieder mal nicht ganz schlau aus der Sache... das habe ich wieder relativ blind kopiert, was mir aber nicht wirklich behagt
 
Zurück