从MySQL链接表创建PHP多维关联数组选择查询
我希望有人能帮我解决这个问题 假设我有3个DB表:从MySQL链接表创建PHP多维关联数组选择查询,php,mysql,performance,multidimensional-array,associative-array,Php,Mysql,Performance,Multidimensional Array,Associative Array,我希望有人能帮我解决这个问题 假设我有3个DB表: Users: user_id, user_name 100, John 101, Jessica Cars: car_id, car_name 30, Corvette 31, BMW UsersCars: user_id, car_id, car_colour 100, 30, Red 101, 30, Green 101, 31, Green (so John got a red corvette and Jessica has a
Users:
user_id, user_name
100, John
101, Jessica
Cars:
car_id, car_name
30, Corvette
31, BMW
UsersCars:
user_id, car_id, car_colour
100, 30, Red
101, 30, Green
101, 31, Green
(so John got a red corvette and Jessica has a green Corvette and a BMW)
我想要返回多维PHP数组的代码,比如:
Array
(
[100] => Array
(
[user_id] => 100
[user_name] => John
[cars] => Array
(
[car_id]=>30,
[car_name]=>'Corvette',
[car_colour]=>'Red'
)
)
[101] => Array
(
[user_id] => 101
[user_name] => Jessica
[cars] => Array
(
[0] => Array
(
[car_id]=>30,
[car_name]=>'Corvette',
[car_colour]=>'Green'
),
[1] => Array
(
[car_id]=>31,
[car_name]=>'BMW',
[car_colour]=>'Green'
)
)
)
)
我有以下SQL
SELECT u.*, c.* FROM Users u
LEFT JOIN UsersCars uc ON u.user_id = uc.user_id
LEFT JOIN Cars c ON uc.car_id = c.car_id
和PHP
$result = mysqli_query($db, $q);
while ($row = mysqli_fetch_assoc($result)) {
$users_with_cars[$row['user_id']] = $row;
}
但这是不对的。有人知道如何解决上述阵列产生的问题吗(考虑到性能)?我不想硬编码“汽车”的例外情况,因为“汽车”可能不止一次发生。我更喜欢只查看$row和$users_和车,当看到一些新值时,它会通过将旧值转换为数组来附加它。也许已经有了一个本机PHP函数?或者更好,也许我的MySQL或整个方法是错误的
任何帮助或提示,不胜感激
问候
已解决更新问题 这里有一个更新,也许我可以帮助别人我最终如何解决它 最后,我总是为一辆或多辆车使用一个数组,并且我调整了表,使其始终以“id”作为列名。这样您就可以轻松地扩展它。参见示例
Users:
id, name
100, John
101, Jessica
Cars:
id, name
30, Corvette
31, BMW
UsersCars:
user_id, car_id, car_colour
100, 30, Red
101, 30, Green
101, 31, Green
$q = 'SELECT u.*, c.id as car_id, c.name as car_name, uc.colour as car_colour FROM Users u
LEFT JOIN UsersCars uc ON u.id = uc.user_id
LEFT JOIN Cars c ON uc.car_id = c.id';
$result = mysqli_query($db, $q);
while ($row = mysqli_fetch_assoc($result)) {
$users_with_cars[] = $row;
}
$joins = array('cars' => array('car_id'=>'id','car_name'=>'name','car_colour'=>'colour'));
$users_with_cars = create_join_array($users_with_cars, $joins);
print_r($users_with_cars);
function create_join_array($rows, $joins){
/* build associative multidimensional array with joined tables from query rows */
foreach((array)$rows as $row){
if (!isset($out[$row['id']])) {
$out[$row['id']] = $row;
}
foreach($joins as $name => $item){
unset($newitem);
foreach($item as $field => $newfield){
unset($out[$row['id']][$field]);
if (!empty($row[$field]))
$newitem[$newfield] = $row[$field];
}
if (!empty($newitem))
$out[$row['id']][$name][$newitem[key($newitem)]] = $newitem;
}
}
return $out;
}
这一切都会产生美丽的阵列:
Array
(
[100] => Array
(
[id] => 100
[name] => John
[cars] => Array
(
[30] => Array
(
[id]=>30
[name]=>'Corvette',
[colour]=>'Red'
)
)
)
[101] => Array
(
[id] => 101
[name] => Jessica
[cars] => Array
(
[30] => Array
(
[id]=>30,
[name]=>'Corvette',
[colour]=>'Green'
),
[31] => Array
(
[id]=>31,
[name]=>'BMW',
[colour]=>'Green'
)
)
)
)
假设用户也可以拥有多辆自行车。然后,您有多个联接数组,您可以轻松地使用左联接绑定并将其添加到联接数组中
$q = 'SELECT u.*, c.id as car_id, c.name as car_name, uc.colour as car_colour, b.id as bike_id, b.name as bike_name FROM Users u
LEFT JOIN UsersCars uc ON u.user_id = uc.user_id
LEFT JOIN Cars c ON uc.car_id = c.id
LEFT JOIN UsersBikes ub ON u.user_id = ub.user_id
LEFT JOIN Bikes b ON ub.bike_id = b.id';
$result = mysqli_query($db, $q);
while ($row = mysqli_fetch_assoc($result)) {
$users_with_cars_bikes[] = $row;
}
$joins = array('cars' => array('car_id'=>'id', 'car_name'=>'name', 'car_colour'=>'colour'),
'bikes' => array('bike_id'=>'id', 'bike_name'=>'name'));
$users_with_cars_bikes = create_join_array($users_with_cars_bikes, $joins);
print_r($users_with_cars_bikes);
会导致类似的结果
Array(
[100] => Array
(
[id] => 100
[name] => John
[cars] => Array
(
[30] => Array
(
[id]=>30
[name]=>'Corvette',
[colour]=>'Red'
)
)
[bikes] => Array
(
[41] => Array
(
[id]=>41
[name]=>'BMX'
)
)
)
)
等等
谢谢大家的帮助:)这是我能想到的。它将(可能)创建一个数组,就像您希望的输出一样。不确定它是否会工作,我在这里写了这个没有测试。让我知道!:)
编辑: 这是我在评论中提到的一个例子:
$result = mysqli_query($db, $q);
while ($row = mysqli_fetch_assoc($result))
{
$count = count($users_with_cars[$row['user_id']]['cars']);
foreach($row AS $key => $value)
{
if(substr($key, 0, 4) == "car_")
{
// Single:
$users_with_cars[$row['user_id']]['cars'][$key] = $value;
// Multiple:
$users_with_cars[$row['user_id']]['cars'][$count][$key] = $value;
}
}
}
不,没有用于此的本机php函数。您必须自己构建阵列。检查以前是否在阵列中保存过用户。如果没有,则存储基本用户信息和随车信息。如果用户存在,则意味着添加car数据。(顺便说一句:对于
[cars]
数组),我只是对某些web服务感到恼火,这些服务将特定变量作为单个字符串或数组返回,而在另一个结果集中作为数组返回。因此,我需要检查客户机上的每个值是否有更多的子项。如果您的数据结构没有因不同的结果集而改变,那么重新读取数据会更容易。因此,您的[cars]
数组应该始终包含任何汽车的“父”数组,即使只有一个entry@feeela是的,我同意thx,我还不确定这个设计选择。当然,您也可以在使用它时使用它:foreach((数组)$cars as$car){}但这并不意味着sense@Sanne如果强制转换的值是对象,则不会(array)new StdClass()
还返回一个数组。但是您将得到的不是包含单个对象的数组(array(new StdClass())
),而是数组中对象的成员。谢谢,是的,我认为这段代码是正确的,这也是Sergey代码的一部分。但基本上,;没有本地的快速解决方案?这让我有点吃惊,因为很多设计都有链接表,需要将其转换为多assoc数组..:/这些解决方案也有点痛苦,因为如果您更改数据库结构(将引擎列添加到汽车中),您还必须修改代码。@Sanne遗憾的是,没有本机函数可以执行类似的操作。这可能很烦人,但这可能是最好的方式。如果您想让它更具动态性,可以在$row
中循环并添加每一列。由于来自cars
的数据以car\u
开头,因此可以检查列是否以car\u
开头,如果是,则将其添加到数组中。这意味着,如果您添加了规范,就不必更改代码。谢谢,启发了我解决方案谢谢,启发了我解决方案
$result = mysqli_query($db, $q);
while ($row = mysqli_fetch_assoc($result))
{
// Add user ID and name to the array
$users_with_cars[$row['user_id']]['user_id'] = $row['user_id'];
$users_with_cars[$row['user_id']]['user_name'] = $row['user_name'];
// Check if this user has cars in the array. If not, this is the first car (see else)
if(isset($users_with_cars[$row['user_id']]['cars']))
{
// Check if there is exactly 1 car in the array
if(count($users_with_cars[$row['user_id']]['cars']) == 1)
{
// If yes, put that car in a 'sub array'
$users_with_cars[$row['user_id']]['cars'] = array(0 => $users_with_cars[$row['user_id']]['cars']);
// Then add the new car
$users_with_cars[$row['user_id']]['cars'][] = array('car_id' => $row['car_id'], 'car_name' => $row['car_name'], 'car_color' => $row['car_color']);
}
else
{
// It already has more than one car in the array. Just add it
$users_with_cars[$row['user_id']]['cars'][] = array('car_id' => $row['car_id'], 'car_name' => $row['car_name'], 'car_color' => $row['car_color']);
}
}
else
{
// Add a single car without 'sub array'
$users_with_cars[$row['user_id']]['cars']['car_id'] = $row['car_id'];
$users_with_cars[$row['user_id']]['cars']['car_name'] = $row['car_name'];
$users_with_cars[$row['user_id']]['cars']['car_color'] = $row['car_color'];
}
}
$result = mysqli_query($db, $q);
while ($row = mysqli_fetch_assoc($result))
{
$count = count($users_with_cars[$row['user_id']]['cars']);
foreach($row AS $key => $value)
{
if(substr($key, 0, 4) == "car_")
{
// Single:
$users_with_cars[$row['user_id']]['cars'][$key] = $value;
// Multiple:
$users_with_cars[$row['user_id']]['cars'][$count][$key] = $value;
}
}
}