简体   繁体   中英

Best way to get data from multiple tables

在此处输入图片说明

I want to get data from 3 tables above and store in an array like this.

在此处输入图片说明

Can only one query join multiple tables and return the array I need?

Or I write query for each table then combine 3 arrays? (Get all IDs in table A, look up the values of table B and C that ID matched)?

Which one is more effecient?

If possible, please write a sample code. Thank you.

Try below query

SELECT a.item,a.item_desc,b.meta_value,c.name
   FROM TableA a 
   JOIN TableB b ON a.id = b.id 
   JOIN tableC c ON c.id = b.id
   ORDER BY a.item_desc

$data = array(); // create a variable to hold the information
while (($row = mysql_fetch_array($result, MYSQL_ASSOC)) !== false){
$data[] = $row; // add the row in to the results (data) array
}

print_r($data); // print result

One mysql query is quicker than 3 (even with joins)

One mysql query can gather the data from all three tables, as shown in another answer. And it will be quicker to do just one query rather than three separate queries.

Joins produce permutations of data

Mysql will return multiple rows, one for each permutation of data when you do join multiple tables. This means that some data, like item id, will be repeated on multiple rows. Given that table A has many entries on table B, and that table A also has many entries on table C the result set will be something like this:

| A1 | B1 | C1 |
| A1 | B1 | C2 |
| A1 | B2 | C1 |
| A1 | B2 | C2 |

Transforming the mysql output into the desired data structure

The following code does the job. You might like to improve it somehow.

<?php
// Connect to the mysql server
$mysqli = new mysqli('localhost', $env['username'], $env['password'], $env['database']);
if ($mysqli->connect_errno) {
    echo 'Failed to connect';
}

echo $mysqli->host_info . "\n";

// SQL query to join 3 tables based on item ID.
// This will return one row for each permutation of data.
// Note that the column 'desc' in the OPs question has been replaced with 'description'
// to avoid a naming conflict with a MYSQL keyword.
$res = $mysqli->query("select distinct a.id, a.item, a.description, b.metakey, b.metavalue, c.name from a join b on a.id = b.item_id join c on a.id = c.item_id order by a.item"); 
print_r($res);

// Transform the mysql output which contains duplicate information
// into the desired data structure as specified in the OPs question.
$output = [];
while($row = $res->fetch_assoc()) {
        // We need to use the row ID (Item ID) to process the mysql rows.

       // Only add the full row if the Item ID has not previously been added.                                                   
        if (!isset($output[$row['id']])) {
            // Form the desired data structure
            $output[$row['id']] = [
                "DATA" => [
                    // The data array is an indexed array.
                    $row['item'],
                    $row['description'],
                ],
                "META" => [
                    // The meta array is an associative array and uses key value pairs.
                    $row['metakey'] => $row['metavalue'],
                ],
                // The extra array is an indexed array.
                "EXTRA" => [  
                    $row['name'],
                ],
            ]; 
        } 
        // Here we fill in the missing data from the partially duplicated mysql rows.
        // We drill down into the output array to check which keys have been added already,
        // and if it hasn't been added we add it.
        if (!isset($output[$row['id']]['META'][$row['metakey']])){
            $output[$row['id']]['META'][$row['metakey']] = $row['metavalue'];
        }
        // Same again, but a slightly different check. This time we are dealing with
        // an indexed array so we need to see if the value has been added.
        if (!in_array($row['name'], $output[$row['id']]['EXTRA'])) {
            $output[$row['id']]['EXTRA'][] = $row['name'];
        }
}

print_r($output);

The above code has been tested. You'll just need to add your own $env array with the appropriate mysql connection details for your mysql server.

References

1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM