从多个表中获取数据的最佳方法

时间:2016-10-13 04:32:21

标签: php mysql arrays database-design pdo

enter image description here

我想从上面的3个表中获取数据并存储在这样的数组中。

enter image description here

只能有一个查询连接多个表并返回我需要的数组吗?

或者我为每个表写查询然后组合3个数组? (获取表A中的所有ID,查找ID匹配的表B和C的值)?

哪一个更有效?

如果可能,请编写示例代码。 谢谢。

2 个答案:

答案 0 :(得分:2)

尝试以下查询

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

答案 1 :(得分:2)

一个mysql查询比3快(即使有连接)

一个mysql查询可以收集来自所有三个表的数据,如另一个答案所示。而且只做一个查询而不是三个单独的查询会更快。

加入产生数据的排列

当您连接多个表时,Mysql将返回多行,每个行对应一次数据排列。这意味着某些数据(如item id)将在多行上重复。鉴于表A在表B上有许多条目,并且表A在表C上也有许多条目,结果集将是这样的:

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

将mysql输出转换为所需的数据结构

以下代码完成了这项工作。你可能想以某种方式改进它。

<?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);

以上代码已经过测试。您只需要为自己的mysql服务器添加自己的$ env数组以及相应的mysql连接详细信息。

参考

1