It seems that recursion is inevitable here. I join Jack's answer, just expand it with PHP code :)
I must warn you that I never executed it, so debugging will be required, but I hope you get this idea. :)
$checked_dependencies = array(); $materials = array(); function materialList( $ids ) { // if we have an array of IDs, condition is ".. in (...)" if(is_array($ids)) { $condition = 'IN ('.implode(',',$ids).')'; // add all to checked dependencies foreach($ids as $id) { $checked_dependencies[] = $id; } }else{ // otherwise, checking for particular ID $condition = "= {$ids}"; // add to checked dependencies $checked_dependencies[] = $ids; } $query = "SELECT t.*, m.materialTypeID, m.quantity AS m_quantity, r.requiredTypeID, r.quantity AS r_quantity FROM invTypes t LEFT JOIN invTypeMaterials m ON t.typeId = m.typeId LEFT JOIN ramTypeRequirements r ON t.typeId = r.typeId WHERE t.typeID {$condition}"; $res = mysqli_query($dbc, $query); // this will be the list of IDs which we need to get $ids_to_check = array(); while($material = mysqli_fetch_assoc($res)) { $materialList[] = $material; // you can get only needed fields // if we didn't check the dependencies already, adding them to the list // (if they aren't there yet) if(!in_array($material['materialTypeId'], $checked_dependencies) && !in_array($material['materialTypeId'], $ids_to_check) && !is_null($material['materialTypeId'])) { $ids_to_check[] = $material['materialTypeId']; } if(!in_array($material['requiredTypeId'], $checked_dependencies) && !in_array($material['requiredTypeId'], $ids_to_check) && !is_null($material['requiredTypeId'])) { $ids_to_check[] = $material['requiredTypeId']; } } // if the result array isn't empty, recursively calling same func if(!empty($ids_to_check)) { materialList($ids_to_check); } }
I used a global array here, but it's easy to overwrite func to return data.
We can also introduce some depth restrictions to avoid too much recursion.
As a rule, I would say that this is not a very convenient (for this task) organization of database data. This is convenient for storing data recursively, like this, but as you can see, it leads to an unknown number of iterations and database queries to get all the dependencies. And it can be expensive (PHP β MySQL β PHP β ...), at each iteration we lose time, especially if the database is on a remote server, as in your case.
Of course, it would be great to rebuild the data structure to be able to immediately get all the requirements, but, as I understand it, you have read-only access to the database. The second solution that comes to my mind is the MySQL recursive stored procedure, which is also not possible here.
In some cases (not usually) it is useful to get as much data as possible in one query and work with it locally to reduce the number of iterations. It is difficult to say whether this is possible here because I do not know the size of the database, structure, etc., But, for example, if all the necessary dependencies are stored in one group, and the groups are not very large, it might be faster to get the whole group information in a single request to a PHP array, and then collect information from this array locally. But - this is just an assumption, and he needs testing and verification.