2

I'm having two tables of data "Item" and "Subsidiary" with the following structure:

ITEM ItmCod ItmName

SUBSIDIARY ItmCodParent ItmCodChild

I need to show a list of Items each with a list of its subsidiaries, like in this json:

{
   "ItmCod":1,
   "ItmName":"BogusItem1",
   "Subsidiaries":
   [
      {
         "ItmCodParent":1,
         "ItmCodChild":15
      },{
         "ItmCodParent":1,
         "ItmCodChild":16      
      }
   ]
},{
   "ItmCod":2,
   "ItmName":"BogusItem2",
   "Subsidiaries":
   [
      {
         "ItmCodParent":2,
         "ItmCodChild":17
      },{
         "ItmCodParent":2,
         "ItmCodChild":18      
      }
   ]
}

How can I add the second result set to the first one to have the nested as shown above. I have this code so far:

$sql = "SELECT ItmCod, ItmName FROM item";

$item_rows = array();

while($item_row = $database->fetch_array_assoc($item_result)){

   $sub_sql = "SELECT ItmCodParent, ItmCodChild FROM subsidiary WHERE subsidiary.ItmCodParent = " . $item_row["ItmCod"];

   $sub_result = $database->query($sub_sql);

   $sub_rows = array();

   while($sub_row = $database->fetch_array_assoc($sub_result)){
      $sub_rows[] = $sub_row;
   }

   $item_rows[] = $item_row;
}

print json_encode($item_rows);

Thanks.

1

3 Answers 3

2

just above the line

$item_rows[] = $item_row;

simply add

$item_row['Subsidiaries']=$sub_rows;
Sign up to request clarification or add additional context in comments.

Comments

1

I would do a single join query like this:

SELECT i.ItmCod AS ItmCod, i.ItmName AS ItmName, s.ItmCodChild AS ItmCodChild
FROM item AS i
INNER JOIN subsidiary AS s
   ON i.ItmCod = s.ItmCodParent

Note I didn't select s.ItmCodParent as this is just redundant to i.ItmCod.

Then build the array like this:

$item_rows = array();
while($item_row = $database->fetch_array_assoc($item_result)){
   $item_rows[(int)$item_row['ItmCod']]['ItmCod'] = $item_row['ItmCod'];
   $item_rows[(int)$item_row['ItmCod']]['ItmName'] = $item_row['ItmCod'];
   $sub_array = array(
       'ItdCodParent' => $item_row['ItmCod'],
       'ItmCodChild' => $item_row['ItmCodChild']
   );
   $item_rows[(int)$item_row['ItmCod']]['Subsidiaries'][] = $sub_array;
}
$item_rows = array_values($item_rows); // reset numerical indexes.
echo json_encode($item_rows);

1 Comment

I tried this solution and lumped all my results from the second query inside the first result from the first query.
0

I wouldn't attempt to solve this with two queries:

$sql = '
    SELECT I.ItmCod, I.ItmName, S.ItmCodChild
    FROM item I
    LEFT JOIN subsidiary S ON (S.ItmCodParent = I.ItmCod)
';

// fetch $item_result with $sql

$item_rows = array();
while ($item_row = $database->fetch_array_assoc($item_result)) {
  $cod = $item_row['ItmCod'];
  if (!array_key_exists($cod, $item_rows)) {
    $item_rows[$cod] = $item_row;
  }

  $item_rows[$cod]['Subsidiaries'] = array(
    'ItmCodParent' => $cod,
    'ItmCodChild' => $item_row['ItmCodChild'],
  );
}

// array_values is because json_encode will keep the keys
// otherwise
print json_encode(array_values($item_rows));

That way, you aren't running an additional query for every single item row to get the subsidiaries (minimizing round-trip time, and letting the database do what it's good at).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.