如何使用PHP数组模拟SQL LEFT JOIN操作?

时间:2014-09-14 18:16:04

标签: php arrays left-join array-merge

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

所以我必须使用PHP从2个不同的服务器中提取2个单独的查询,然后使用PHP将它们联合起来。

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

所以我有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] =>

        )
)

7 个答案:

答案 0 :(得分:3)

此功能模拟左连接操作

   //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');

//假设左数组"中的列名不同但具有相同的对应值"

,可以像这样使用该函数
$final_array = left_join_array($left, $right, 'phone_call_id', 'p_c_id');

答案 1 :(得分:1)

嗨你可以尝试这段代码,这会给你一个类似于左外连接的合并数组:

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

您将从右侧数组中获取带有前缀'右_'

的字段

答案 2 :(得分:1)

我遇到了类似的问题,迫使我不得不使用这种操作。但是接受的答案使我对所有结果都没有价值。我需要做的就是在上一次break迭代中添加一个foreach

以防万一我再次偶然发现相同的问题,我会在此处发布

我遇到的情况是这样的:

scenario

当我在这里使用接受的答案时,我得到的是这样的东西:

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

wrong_result

这不是我想要的结果,因为即使在正确的表上有匹配的数据,也都是null,这是因为foreach的下一次迭代将正确的值替换为{{ 1}}。

我要做的是在最后一个null上添加一个break,并在附加值上添加前缀,以避免替换左表(为安全起见,以防万一我有相同的名称列在表格之间)

foreach

desiredresult

这是我想要的结果。

答案 3 :(得分:0)

试试这个(假设您的空'phone_call_id'和'accout_id'值为空):

$joined_array = array();
foreach($right_array as $right_row){
    $phone_call_id = $right_row['phone_call_id'];
    $account_id    = $right_row['account_id'];
    foreach($left_array as $i => $left_row){
        if($left_row['phone_call_id'] === $phone_call_id){
            $left_row['account_id'] = $account_id;
            $joined_array[]         = $left_row;
        }
    }
}
//And here, we have to identify rows with empty 'phone_call_id'
foreach($left_array as $left_row){
    if($left_row['phone_call_id'] === null){
        $left_row['account_id'] = null;
        $joined_array[]         = $left_row;
    }
}

答案 4 :(得分:0)

一个简单的解决方案,

为我工作使用了这个,

function arrayLeftJoin($left,$right){
    foreach ($left as $lkey => $lvalue) {
        foreach ($right as $rkey => $rvalue) {
            if($lkey==$rkey){
                unset($left[$lkey]);
            }
        }
    }
    return $left;
}

全部谢谢

答案 5 :(得分:0)

尽量避免这种操作。如果可以,尝试将所有数据库放到同一服务器上并使用SQL JOIN-s。 PHP不是MYSQL。 PHP不专用于(左,右等)连接表。例如如果你在mysql返回的左表中有大量的记录并将其作为结果放在数组中,你可能会面临内存问题的大麻烦。使用MYSQL执行MYSQL作业,使用PHP执行PHP作业。这样你就可以节省:时间,表演和神经元。 :)

答案 6 :(得分:0)

好的,旧话题了,但我们永远不知道...可能有用。 只是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;
 }