如何使用PHP数组模拟SQL左连接操作?

如何使用PHP数组模拟SQL左连接操作?,php,arrays,left-join,array-merge,Php,Arrays,Left Join,Array Merge,我有一个连接到多个服务器的应用程序。其中一台服务器的ID是位于不同服务器上的表的外键。这里的问题是MySQL不支持链接服务器,所以我不能运行一个左查询,左查询将左连接位于不同服务器上的两个表 因此,我必须使用PHP从两个不同的服务器中提取两个单独的查询,然后它们使用PHP连接起来 请注意,下面列出的数组键需要是动态的。我不能使用固定名称,因为不同的查询将有不同的列名。下面的示例使用phone_call_id作为连接两个数组的键,并结合了列名。如果$right_数组有更多列,则需要将这些列添加到最

我有一个连接到多个服务器的应用程序。其中一台服务器的ID是位于不同服务器上的表的外键。这里的问题是MySQL不支持链接服务器,所以我不能运行一个左查询,左查询将左连接位于不同服务器上的两个表

因此,我必须使用PHP从两个不同的服务器中提取两个单独的查询,然后它们使用PHP连接起来

请注意,下面列出的数组键需要是动态的。我不能使用固定名称,因为不同的查询将有不同的列名。下面的示例使用phone_call_id作为连接两个数组的键,并结合了列名。如果$right_数组有更多列,则需要将这些列添加到最终数组中

所以我有2个数组

$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;
}