I often come across a situation where I have a 1:N relation, e.g. a table of items and another table with additional metadata / attributes for every item.
Consider this example:
users +-----------+-----------+ | user_id | username | +-----------+-----------+ | 1 | max | | 2 | john | | 3 | elton | | 4 | tom | | 5 | dave | +-----------+-----------+ user_profile_data +-----+-----------+-----------+ | uid | field_id | field_val | +-----+-----------+-----------+ | 1 | 1 | a | | 1 | 2 | b | | 2 | 1 | c | | 2 | 2 | d | | 3 | 1 | e | | 3 | 2 | f | | 3 | 3 | g | | 4 | 1 | h | | 4 | 4 | i | +-----+-----------+-----------+
Now I have two questions: I want to select extended user-data, every (uid, field_id) combination is unique, usually I do it this way:
SELECT u.user_id, u.username, upd.field_id, upd.field_val FROM users u LEFT JOIN user_profile_data upd ON u.user_id = upd.uid
I get a row for every user/field combination and would need to “re-sort” in php because usually I want to have an array which contains every User with a Subarray of extended attributes, for example like this:
$users = array(1 => array('username' => max, 'data' => array(1 => 'a', 2 => 'b')), 2 => array('username' => 'john', ...));
Is there a standardized way of simplifying this and/or what’s the best-practise in such cases? Is there already something build-in in PHP (not an external SQL framework)?
Thanks
Advertisement
Answer
Something like this should work (didn’t test, sorry)
$users = []; foreach($results as $result) { // assuming $results contains DB results if (!isset($users[$result['user_id']])) { $user[$result['user_id']] = []; $user[$result['user_id']]['username'] = $result['username']; $user[$result['user_id']]['data'] = []; } $user[$result['user_id']]['data'][$result['field_id']] = $result['field_val']; }
This is not generic code, you should adapt it for each table schema, but I do not know a simplier way to do it. Or you spam your SQL server by not doing “JOIN” query… :/ (I think your sql is better 🙂 )