[PHP/Smarty] Abfrage über 2 Tabellen + foreach

Renegade

Well-known member
ID: 159167
L
3 August 2006
851
77
Huhu :)

Ich steh grad' mal wieder auf dem Schlauch und komm nicht weiter.

Ich möchte eine DB-Abfrage über zwei Tabellen machen, wobei das Ergebnis der ersten Tabellenabfrage ausschlaggebend für die zweite Tabellenabfrage ist.

PHP:
  $query = "SELECT
               id
               ... ";
  $result = mysql_query($query) OR die(mysql_error());

  $arr = array();
  while($row = mysql_fetch_assoc($result)) {
    $arr[] = $row;

    $query2 = "SELECT
                 id,
                 name
                 ...
               WHERE
                 id_new = ".$row['id']."
                 ...";
    $result2 = mysql_query($query2) OR die(mysql_error());

    $arr2 = array();
    while($row2 = mysql_fetch_assoc($result2)) {
      $arr2[] = $row2;
    }
  }

Und zum Schluss:

PHP:
$smarty->assign('arr', $arr);
$smarty->assign('arr2', $arr2);


Die Templatedatei sieht so aus:

Code:
{foreach from=$arr item=arr}
  {$arr.id} <br/>
  {foreach from=$arr2 item=arr2}
    {$arr2.name} <br/>
  {/foreach}
<br/>
{/foreach}

Leider klappt das ganze nicht wirklich, aber ich weiß auch nicht wie ich die doppelte foreach Schleife machen soll.
Könnt ihr mir helfen?
 
Vielleicht kannst du es mit einem intelligenten JOIN in deiner SQL-Abfrage umgehen! :p

Hi,

Meinst du damit ich könnte hier in dem Beispiel mit inner Join arbeiten?
Aber wie muss dann der foreach in der Templatedatei gestalltet sein?
Ich will ja z.B. so eine Ausgabe:

Erste ID aus der ersten Abfrage
Namen die als id_new die id aus der ersten Abfrage haben
Zweite ID aus der ersten Abfrage
Namen die als id_new die zweite id aus der ersten Abfrage haben
...
Also:

1
Test (1)
Test2 (1)
Test3 (1)

2
Test (2)
Test2 (2)
Test3 (2)
 
Vielleicht kannst du es mit einem intelligenten JOIN in deiner SQL-Abfrage umgehen! :p
Nicht vielleicht - sowas macht man auf jeden Fall mit einem JOIN:
Code:
SELECT id,name,pillepalle FROM Tabelle1 t1 
  LEFT JOIN Tabelle2 t2 ON t1.id = t2.id_new
  WHERE t1.pillepalle = 'deinKriteriumWhatever';
Bei großen Abfrageergebnissen in wilden Schleifen machst Du sonst nämlich jeden Server platt ...
 
Danke euch beiden, die Abfrage habe ich jetzt geschafft.

Nur wie muss ich nun die foreach Bedingung in der Templatedatei machen?
 
Danke euch beiden, die Abfrage habe ich jetzt geschafft.

Nur wie muss ich nun die foreach Bedingung in der Templatedatei machen?

Bei einer 1:1 Relation kannst du alles ganz normal ausgeben, bei einer 1:n Relation (sprich 1 Datensatz aus Tabelle 1 : viele Datensätze aus Tabelle 2 (mit Fremdschlüssel von Tabelle 2 = Primary Key von Tabelle 1)) kann´s aber ein bisschen tricky werden (da musst du dir selbst was basteln, sollte mit if-Bedingungen aber zu lösen sein).
 
Wie oben beschrieben ist es eine 1:n Beziehung. Kannst du mir ein Denkanstoß geben?

So würde ich es spontan lösen:

Code:
// Pseudocode
foreach(results as result) { // result['id'] -> 1er Merkmal der ersten Tabelle
 if(cache != result['id']) iterate = true;
 cache = result['id'];
 if(iterate === true) {
   // Ausgabe der Werte der zweiten Tabelle
 }
}

edit: Wo stand was von einer 1:n Relation? Hab nix gefunden :)
 
Danke dir :)

Hmm, ich meinte eigentlich die foreach Schleife in Smarty ({foreach} {/foreach}).

Hiermit wollte ich die 1:n Beziehung andeuten.
Erste ID aus der ersten Abfrage
Namen die als id_new die id aus der ersten Abfrage haben
Zweite ID aus der ersten Abfrage
Namen die als id_new die zweite id aus der ersten Abfrage haben
...
Also:

1
Test (1)
Test2 (1)
Test3 (1)

2
Test (2)
Test2 (2)
Test3 (2)
 
Mal als Anregung:
PHP:
$array = array(
  'foo' => array(
    'name' => 'foo',
    'items' => array('a', 'b', 'c')
  ),
  'bar' => array(
    'name' => 'bar',
    'items' => array(1,2,3)
  )
);
$smarty->assign('array', $array);
Das entsprechende Template:
HTML:
{foreach from=$array item="data"}
  <h1>{$data.name}</h1>
  <ul>
  {foreach from=$data.items item="item"}
    <li>{$item}</li>
  {/foreach}
  </ul>
{/foreach}
Wird Dir hoffentlich helfen, das Ganze zu verstehen.
 
Mal als Anregung:
PHP:
$array = array(
  'foo' => array(
    'name' => 'foo',
    'items' => array('a', 'b', 'c')
  ),
  'bar' => array(
    'name' => 'bar',
    'items' => array(1,2,3)
  )
);
$smarty->assign('array', $array);
Das entsprechende Template:
HTML:
{foreach from=$array item="data"}
  <h1>{$data.name}</h1>
  <ul>
  {foreach from=$data.items item="item"}
    <li>{$item}</li>
  {/foreach}
  </ul>
{/foreach}
Wird Dir hoffentlich helfen, das Ganze zu verstehen.

Deins klappt natürlich wunderbar, danke :)
Nur mein Array ist anders aufgebaut:

array(3) {
[0]=>
array(3) {
["id_id"] => "1"
["name"] => "Name1"
["id"] => "1" }
[1]=>
array(7) {
["id_id"] => "2"
["name"] => "Name2"
["id"] => "1" }
[2]=>
array(7) {
["id_id"] => "3"
["name"] => "Name3"
["id"] => "2" }
}
 
Vielleicht solltest Du dann überlegen, Dein Array anders aufzubauen... ;)

So wie's momentan bei Dir aussieht, würd das in unnötig viel Gefrickel enden.
 
Vielleicht solltest Du dann überlegen, Dein Array anders aufzubauen... ;)

So wie's momentan bei Dir aussieht, würd das in unnötig viel Gefrickel enden.

Nichts lieber als das, denn ich finde auch, dass es viel zu "unübersichtlich" ist, aber wie kann ich den Array anders aufbauen bei einer DB Abfrage? Bis jetzt habe ich es so gemacht:

PHP:
  $result = mysql_query($query) OR die(mysql_error());

  $array = array();
  while($row = mysql_fetch_assoc($result)) {
    $array[] = $row;
  }
 
Nuja, Du hast ja 'nen Primärschlüssel, der auch in Smarty die einzelnen Blöcke voneinander trennen wird. Anhand von diesem Schlüssel kannst Du dann das Array aufbauen:
PHP:
$query = "SELECT a.id, a.foo, b.bar FROM a LEFT JOIN b USING(id)";
$db->query($sql);

$results = array();
while ($row = $db->fetch_array())
{
  if (empty($results[$row['id']]))
  {
    $results[$row['id']] = array(
      'name' => $row['foo'],
      'items' => array()
  }
  array_push($results[$row['id']]['items'], $row['bar']);
}
Was Du nun in Zeile 13 in das Array reinschaufelst, bleibt Dir überlassen. Das können Arrays sein oder auch einfache Datentypen.

Hope that helps.
 
Hi,
Das klappt sehr gut, danke :)

Eine (hoffentlich) letze Frage noch:
Kann ich
'items' => array()
als assoziatives Array "definieren"?
Wenn ich es so mache: 'items' => array('name', 'name2'), wie kann ich dann array_push verwenden?
 
Du kannst folgendes machen:
PHP:
  // [...]
  // array_push($results[$row['id']]['items'], $row['bar'])
  $results[$row['id']]['items'][$row['bar']] = $row['bar'];
Dadurch wird das Ganze dann zu 'nem assoziativen Array.
 
Huhu,
Also langsam habe ich das richtig gut verstanden, ich muss jetzt nurnoch den Array basteln :) Danke an euch :)

Habs geschafft. Großes Danke an euch :)
 
Zuletzt bearbeitet: