如何使用PHP数组模拟SQL左连接操作?
我有一个连接到多个服务器的应用程序。其中一台服务器的ID是位于不同服务器上的表的外键。这里的问题是MySQL不支持链接服务器,所以我不能运行一个左查询,左查询将左连接位于不同服务器上的两个表 因此,我必须使用PHP从两个不同的服务器中提取两个单独的查询,然后它们使用PHP连接起来 请注意,下面列出的数组键需要是动态的。我不能使用固定名称,因为不同的查询将有不同的列名。下面的示例使用phone_call_id作为连接两个数组的键,并结合了列名。如果$right_数组有更多列,则需要将这些列添加到最终数组中 所以我有2个数组如何使用PHP数组模拟SQL左连接操作?,php,arrays,left-join,array-merge,Php,Arrays,Left Join,Array Merge,我有一个连接到多个服务器的应用程序。其中一台服务器的ID是位于不同服务器上的表的外键。这里的问题是MySQL不支持链接服务器,所以我不能运行一个左查询,左查询将左连接位于不同服务器上的两个表 因此,我必须使用PHP从两个不同的服务器中提取两个单独的查询,然后它们使用PHP连接起来 请注意,下面列出的数组键需要是动态的。我不能使用固定名称,因为不同的查询将有不同的列名。下面的示例使用phone_call_id作为连接两个数组的键,并结合了列名。如果$right_数组有更多列,则需要将这些列添加到最
$left_array =
Array
(
[0] => Array
(
[id] => 1
[start_on] => 2014-09-14 19:50:00
[end_on] => 2014-09-14 19:51:00
[subject] => This is a new event
[client_id] =>
[all_day_event] => 0
[event_type] => Event
[phone_call_id] => 122
)
[1] => Array
(
[id] => 2
[start_on] => 2014-09-15 05:53:00
[end_on] => 2014-09-15 06:53:00
[subject] => This is a new event
[client_id] =>
[all_day_event] => 0
[event_type] => Event
[phone_call_id] => 123
)
[2] => Array
(
[id] => 3
[start_on] => 2014-09-15 05:53:00
[end_on] => 2014-09-15 06:53:00
[subject] => This is a new event
[client_id] =>
[all_day_event] => 0
[event_type] => Event
[phone_call_id] =>
)
)
正确的数组如下所示
$right_array =
Array
(
[0] => Array
(
[account_id] => 1
[phone_call_id] => 122
)
[1] => Array
(
[account_id] => 2
[phone_call_id] => 123
)
)
结果需要类似于此数组
$joined_array =
Array
(
[0] => Array
(
[id] => 1
[start_on] => 2014-09-14 19:50:00
[end_on] => 2014-09-14 19:51:00
[subject] => This is a new event
[client_id] =>
[all_day_event] => 0
[event_type] => Event
[phone_call_id] => 122
[account_id] => 1
)
[1] => Array
(
[id] => 2
[start_on] => 2014-09-15 05:53:00
[end_on] => 2014-09-15 06:53:00
[subject] => This is a new event
[client_id] =>
[all_day_event] => 0
[event_type] => Event
[phone_call_id] => 123
[account_id] => 2
)
[2] => Array
(
[id] => 3
[start_on] => 2014-09-15 05:53:00
[end_on] => 2014-09-15 06:53:00
[subject] => This is a new event
[client_id] =>
[all_day_event] => 0
[event_type] => Event
[phone_call_id] =>
[account_id] =>
)
)
尝试此操作(假设您的空“phone\u call\u id”和“account\u id”值为空):
您好,您可以尝试这段代码,这将为您提供一个类似于左外联接的合并数组:
foreach($left_array as $k => $v){
foreach($right_array as $kk => $vv){
if($v['id'] == $vv['account_id']){
foreach($vv as $key => $val){
$left_array[$k]['right_'.$key] = $val;
}
}
}
}
您将从右数组中获得前缀为“right”的字段。此函数模拟左连接操作
//function to simulate the left join
function left_join_array($left, $right, $left_join_on, $right_join_on = NULL){
$final= array();
if(empty($right_join_on))
$right_join_on = $left_join_on;
foreach($left AS $k => $v){
$final[$k] = $v;
foreach($right AS $kk => $vv){
if($v[$left_join_on] == $vv[$right_join_on]){
foreach($vv AS $key => $val)
$final[$k][$key] = $val;
} else {
foreach($vv AS $key => $val)
$final[$k][$key] = NULL;
}
}
}
return $final;
}
//假设左数组中的列名与右数组中的列名相同,则可以这样使用该函数
$final_array = left_join_array($left, $right, 'phone_call_id');
//假设左侧数组中的列名“不同,但具有相同的对应值”,则可以这样使用该函数
一个简单的解决方案
为我工作用这个
function arrayLeftJoin($left,$right){
foreach ($left as $lkey => $lvalue) {
foreach ($right as $rkey => $rvalue) {
if($lkey==$rkey){
unset($left[$lkey]);
}
}
}
return $left;
}
谢谢大家尽量避免这种操作。如果可以,请尝试将所有数据库放在同一台服务器上,并使用SQL JOIN-s。PHP不是MYSQL。PHP不是专用于(左、右等)联接表的。e、 g.如果mysql返回的左表中有大量记录并作为结果放入数组中,那么内存问题会给您带来很大的麻烦。使用MYSQL做MYSQL作业,使用PHP做PHP作业。这样您将节省:时间、性能和时间。:) 好吧,老话题,但我们永远不知道……可能有用。 只是对Jaylen解决方案的一点更新
function left_join_array($left, $right, $left_join_on, $right_join_on = NULL){
$final= array();
if(empty($right_join_on))
$right_join_on = $left_join_on;
foreach($left AS $k => $v){
$final[$k] = $v;
foreach($right AS $kk => $vv){
if($v[$left_join_on] === $vv[$right_join_on] ){
foreach($vv AS $key => $val)
$final[$k][$key] = $val;
} else if(!isset($final[$k][$right_join_on])) {
foreach($vv AS $key => $val)
$final[$k][$key] = NULL;
}
}
}
return $final;
}
我遇到了类似的问题,迫使我使用这种操作。但被接受的答案在所有结果上都给我空值。我所需要做的就是在最后一次
foreach
迭代中添加一个break
为了防止我再次遇到同样的问题,我将在这里发布这个
我的场景是这样的:
//function to simulate the left join
function left_join_array($left, $right, $left_join_on, $right_join_on = NULL){
$final= array();
if(empty($right_join_on))
$right_join_on = $left_join_on;
foreach($left AS $k => $v){
$final[$k] = $v;
foreach($right AS $kk => $vv){
if($v[$left_join_on] == $vv[$right_join_on]){
foreach($vv AS $key => $val)
$final[$k][$key] = $val;
} else {
foreach($vv AS $key => $val)
$final[$k][$key] = NULL;
}
}
}
return $final;
}
当我在这里使用公认的答案时,我得到了如下结果:
//function to simulate the left join
function left_join_array($left, $right, $left_join_on, $right_join_on = NULL){
$final= array();
if(empty($right_join_on))
$right_join_on = $left_join_on;
foreach($left AS $k => $v){
$final[$k] = $v;
foreach($right AS $kk => $vv){
if($v[$left_join_on] == $vv[$right_join_on]){
foreach($vv AS $key => $val)
$final[$k][$key] = $val;
} else {
foreach($vv AS $key => $val)
$final[$k][$key] = NULL;
}
}
}
return $final;
}
这不是我想要的结果,因为所有内容都是null
,即使正确的表上有匹配的数据,这是因为foreach
的下一次迭代将正确的值替换为null
我要做的是在最后一个foreach
上添加一个break
,并在附加值上添加前缀,以避免替换左表(为了安全起见,以防表与表之间有相同的名称列)
这就是我想要的结果。嗨,我对你的代码做了一点修改,使之适合我的需要。但我现在遇到的问题是,当phone\u call\u id为空时,数组中就会丢失一个单元格。我会把我现在的代码放在我的帖子里,这样你就可以看一看了。对不起,我想我没有明白你想说的话。根据逻辑,如果某个字段为null或空,它将只返回相同的值,对吗?请输入密码。我将对此进行检查,并尝试给出合适的答案。:)我修复了该函数,并将其作为一个答案发布,以帮助他人。感谢您为我提供了解决问题所需的帮助。您可以看看这个答案,如果您使用的是在不同服务器上有表的分布式系统,该怎么办?您可能会说,在这种情况下,您遇到了麻烦(在这种情况下,您将不得不使用PHP来模拟连接…但是,您很快就会面临我前面描述的问题。尤其是在包含很多行的表(如果您有这样的表)上的左连接情况下。在某些情况下,您可能会遇到无法解决的问题。
//function to simulate the left join
function left_join_array($left, $right, $left_join_on, $right_join_on = NULL){
$final= array();
if(empty($right_join_on))
$right_join_on = $left_join_on;
foreach($left AS $k => $v){
$final[$k] = $v;
foreach($right AS $kk => $vv){
if($v[$left_join_on] == $vv[$right_join_on]){
foreach($vv AS $key => $val)
$final[$k][$key] = $val;
} else {
foreach($vv AS $key => $val)
$final[$k][$key] = NULL;
}
}
}
return $final;
}
//function to simulate the left join
function left_join_array($left, $right, $left_join_on, $right_join_on = NULL)
{
$final = array();
if (empty($right_join_on))
$right_join_on = $left_join_on;
foreach ($left as $k => $v) {
$final[$k] = $v;
foreach ($right as $kk => $vv) {
if ($v[$left_join_on] == $vv[$right_join_on]) {
foreach ($vv as $key => $val)
$final[$k]['_' . $key] = $val; /* add prefix on the key */
break; /* add break here */
} else {
foreach ($vv as $key => $val)
$final[$k]['_' . $key] = NULL; /* add prefix on the key */
}
}
}
return $final;
}