2008-12-10 8 views
4

En venant de another question of mine où j'ai appris à ne JAMAIS utiliser les requêtes db dans les boucles, je dois donc apprendre comment extraire toutes les données de façon pratique avant de les parcourir.PHP/mySQL - comment récupérer des lignes imbriquées dans un tableau multidimensionnel

Disons que j'ai deux tables 'scales' et 'items'. Chaque élément dans les éléments appartient à une échelle dans les échelles et est lié à une clé étrangère (scaleID). Je veux extraire toutes ces données dans une structure de tableau dans une requête de telle sorte que la première dimension soit toutes les échelles avec toutes les colonnes et imbriquées dedans, tous les éléments d'une échelle toutes les colonnes.

Résultat serait quelque chose comme ça:

scale 1, scaleParam1, scaleParam2, ... 
....item1, itemParam1, itemParam2, ... 
....item2, itemParam1, itemParam2, ... 
scale 2, scaleParam2, scaleParam2, ... 
....item1, itemParam1, itemParam2, ... 
....item2, itemParam1, itemParam2, ... 

Jusqu'à présent, je l'ai fait surtout à gauche pour se joint à un à-un. C'est un one-to-many et je ne peux pas m'en sortir.

Est-il un droit se joindre, pourrait-il être fait aussi avec une sous-requête, comment obtenir les lignes complètes extérieures aussi bien en ...

plus tard, je voudrais itérer avec des boucles foreach imbriquées .

Peut-être juste que j'ai un mal de tête ...

Répondre

6

La requête devrait ressembler à ceci:

SELECT * FROM scales 
INNER JOIN items ON scales.id = items.scale_id 

Si vous voulez itérer à travers lo niché opérations, vous aurez besoin de tirer ces données dans un tableau - j'espère que vous ne reculez pas tellement que ça va manger trop de mémoire.

$scales = array(); 

while ($row = mysql_fetch_assoc($data)) 
{ 
    if (!isset($scales[$row['scale_id']])) 
    { 
     $row['items'] = array(); 
     $scales[$row['scale_id']] = $row; 
    } 

    $scales[$row['scale_id']]['items'][] = $row; 
} 

Ensuite, vous pouvez boucle à travers:

foreach ($scales as $scale) 
{ 
    foreach ($scale['items'] as $item) 
     ; //... do stuff 
} 

Note: ceci est un peu naïve dans cette échelle de $ et $ l'article contiendra les deux champs des deux tables ... si c'est un problème alors vous avez besoin pour changer les affectations dans la boucle ci-dessus pour extraire seulement les champs que vous voulez.

+0

wow, vous avez plein de réponses acceptées, incroyable. merci pour celui-ci, pourrait aussi finir au top. – markus

+1

En ce qui concerne la question qui a engendré celui-ci, et à votre commentaire sur manger trop de mémoire, je préfère avoir un grand tableau, disons 1mb de RAM que d'exécuter plusieurs (douzaines?) De requêtes. – TravisO

+0

En outre, bon travail sur l'utilisation de mysql_fetch_assoc, beaucoup de gens font mysql_fetch_array qui est inefficace. – TravisO

1

Il est peut-être plus facile d'abord obtenir toutes les échelles, tous les articles.

//first get scales 
while ($row = fetchrowfunctionhere()) { 
    $scale = $scales->createFromArray($row); 
} 

//then get items 
$lastId = null; 
while ($row = fetchrowfunctionhere()) { 
    $scaleId = $row['scaleID']; 
    if ($lastId != $scaleId) { 
     $scale = $scales->getByScaleId($scaleId); 
    } 
    $item = $items->createFromArray($row); 
    $scale->addItem($item); 
    $lastId = $scaleId; 
} 

ou tout un sql

$lastId = null; 
while ($row = fetchrowfunctionhere()) { 
    $scaleData = array_slice($row, 0, 5, true); 
    $itemData = array_slice($row, 5, 5, true); 
    $scaleId = $scaleData['scaleID']; 
    if ($lastId != $scaleId) { 
     $scale = $scales->createFromArray($scaleData); 
    } 
    $item = $items->createFromArray($itemData); 
    $scale->addItem($item); 
    $lastId = $scaleId; 
} 

tout comme un éventail heureux

while ($row = fetchrowfunctionhere()) { 
    $scaleData = array_slice($row, 0, 5, true); 
    $itemData = array_slice($row, 5, 5, true); 
    $scaleId = $scaleData['scaleID']; 
    if (!isset($scales[$scaleId])) { 
     $scales[$scaleId] = $scaleData; 
    } 
    $itemId = $itemData['itemID']; 
    $scales[$scaleId]['items'][$itemId] = $itemData; 
} 
+0

Je dois admettre que je vais devoir étudier vos solutions puisque je ne comprends pas exactement ce qu'elles font. – markus

+0

Les 2 premiers sont des objets, ce qui le rend plus facile. Le 3ème est avec des tableaux. Vous n'avez pas spécifié mysql dans votre texte (mais je vois maintenant la balise mysql) alors j'ai écrit un nom de fonction générique au lieu de mysql_fetch_assoc. – OIS

Questions connexes