使用包含foreach的结果集的两个数组对项目进行分组和求和

时间:2015-11-22 18:00:31

标签: php arrays foreach

我循环遍历两个存储过程的结果集,根据两个过程中的字段获取最终结果。

以下是两个结果集:

- 获取包含或不包含数据的所有customers

| id |   name  | parentID | calls | type |  // there are two types of calls:1 and 2
+----+---------+----------+-------+------+
|  8 | Telekom |    80    |  100  |   1  |  // we can have same customer with both types of calls
|  8 | Telekom |    80    |   10  |   2  |
| 16 |  Orange |     7    |   50  |   2  |  // we can have one type of call and NULL..
| 16 |  Orange |     7    |  NULL | NULL |  // ..for the same customer
|  9 | Verizon |     2    |  NULL | NULL |  
| 18 |   T&T   |    108   |   30  |   1  |  
| 20 |  Sprint |    33    |  120  |   1  |
| 20 |  Sprint |    33    |   60  |   2  |
| 17 | CellCom |    99    |  NULL | NULL |  // we can have a single..
|  1 | T-Mobile|    14    |   85  |   2  |  //  ..NULL or type of call..
| 34 | US-Cell |    27    |  240  |   1  |  // ..for a single customer

- 获取所有subcustomers数据

| id |      name     | parentID | calls | type |
+----+---------------+----------+-------+------+
| 44 |     CallMe    |     8    |   20  |   1  |
| 72 |    DialNow    |    16    |    5  |   1  |
| 72 |    DialNow    |    16    |   15  |   2  |
| 13 |    Online4U   |     9    |   10  |   1  |
| 22 | TeleSolutions |     9    |   30  |   1  |
|  4 |    FonezInc   |     9    |    5  |   2  |
| 23 |  MobileSelect |     9    |   10  |   2  |
| 10 |      Digi     |    20    |  100  |   1  |
| 11 |    Vodafone   |    20    |   40  |   2  |

所需的结果应如下所示。如果客户拥有calls的子客户(subustomer.parentID = customer.id),请根据正确的type将这些调用添加到客户,否则向客户显示数据。

| id |   name  | parentID | calls | type |
+----+---------+----------+-------+------+
|  8 | Telekom |    80    |  120  |   1  |
|  8 | Telekom |    80    |   10  |   2  |
| 16 |  Orange |     7    |   5   |   1  |
| 16 |  Orange |     7    |   65  |   2  |
|  9 | Verizon |     2    |   40  |   1  |
|  9 | Verizon |     2    |   15  |   2  |
| 18 |   T&T   |    108   |   30  |   1  |
| 20 |  Sprint |    33    |  220  |   1  |
| 20 |  Sprint |    33    |  100  |   2  |
|  1 | T-Mobile|    14    |   85  |   2  |
| 34 | US-Cell |    27    |  240  |   1  |

上述内容应使用PHP获得。

这是我的PHP: 包含结果集的两个数组是$customers$subcustomers

foreach($customers as $customer)
{
    foreach($subcustomers as $subcustomer)
    {
        if($subcustomer['parentID'] == $customer['id'])
        {
            if(($customer['type'] == null || $customer['type'] == "1") && $subcustomer['type'] == "1") // ??
            {
                $keyi = $customer['name'] . '/' . $subcustomer['type'] . '/' . $customer['id'];

                if(isset($mapi[$keyi])) {
                      $out['inbound'][$mapi[$keyi]]['count'] += $subcustomer['calls'];
                }
                else {
                    $out['inbound'][$ii] = array(
                            'name' => $customer['name'],
                            'label' => 'Inbound Calls',
                            'count' => $subcustomer['calls'],
                            'customerid' => $customer['id'],
                    );
                    $mapi[$keyi] = $ii++;
                }                                                                       
            }
            if(($customer['type'] == null || $customer['type'] == "2") && $subcustomer['type'] == "2") // ??
            {       
                $keyo = $customer['name'] . '/' . $subcustomer['type'] . '/' . $customer['id'];

                if(isset($mapo[$keyo])) {
                      $out['outbound'][$mapo[$keyo]]['count'] += $subcustomer['calls'];
                }
                else {
                    $out['outbound'][$io] = array(
                            'name' => $customer['name'],
                            'label' => 'Outbound Calls',
                            'count' => $subcustomer['calls'],
                            'customerid' => $customer['id'],
                    );
                    $mapo[$keyo] = $io++;
                }               
            }
        }
    }

    if($customer['calls'] != null) //outside of subcustomers foreach
    {                            
        if($customer['type'] == "1"){ 
            $chartInbound['name'] = $customer['name'];
            $chartInbound['label'] = "Inbound Calls";
            $chartInbound['count'] = $customer['calls'];
            $chartInbound['customerid'] = $customer['id'];

            array_push($out1['chart'], $chartInbound);
        }
        if($customer['type'] == "2"){
            $chartOutbound['name'] = $customer['name'];
            $chartOutbound['label'] = "Outbound Calls";
            $chartOutbound['count'] = $customer['calls'];
            $chartOutbound['customerid'] = $customer['id'];

            array_push($out1['chart'], $chartOutbound);
        }
    }
}
                $outSub['chart'] = array_merge($out['inbound'], $out['outbound']);

                $out['chart'] = array_merge($outSub['chart'], $out1['chart']);

我在上面的代码中遇到的问题是它没有正确地添加调用,无论是添加多少调用还是少量调用null类型或类型1或类型2调用。我认为条件或某些代码逻辑不正确。

编辑:

上述问题是this帖子的延续。

输出应具有以下相同的结构:

Array
(
    [0] => Array  //indexes should be incremented, starting from 0
        (
            [name] => Telekom
            [label] => Inbound Calls  // label = type, type 1 = Inbound Calls
            [count] => 120
            [customerid] => 6
        )

    [1] => Array
        (
            [name] => Telekom
            [label] => Outbound Calls // type 2 = Outbound Calls
            [count] => 10
            [customerid] => 6
        )

    [2] => Array
        (
            [name] => Orange
            [label] => Inbound Calls
            [count] => 5
            [customerid] => 16
        )

    [3] => Array
        (
            [name] => Orange
            [label] => Outbound Calls
            [count] => 65
            [customerid] => 16
        )

    [4] => Array
        (
            [name] => Verizon
            [label] => Inbound Calls
            [count] => 40
            [id] => 9
        )

    [5] => Array
        (
            [name] => Verizon
            [label] => Outbound Calls
            [count] => 15
            [customerid] => 9
        )
    [6] => Array
        (
            [name] => T&T
            [label] => Inbound Calls
            [count] => 30
            [id] => 18
        )

    [7] => Array
        (
            [name] => Sprint
            [label] => Inbound Calls
            [count] => 220
            [customerid] => 20
        )
    [8] => Array
        (
            [name] => Sprint
            [label] => Outbound Calls
            [count] => 100
            [customerid] => 20
        )
    [9] => Array
        (
            [name] => T-Mobile
            [label] => Outbound Calls
            [count] => 85
            [customerid] => 1
        )
    [10] => Array
        (
            [name] => US-Cell
            [label] => Inbound Calls
            [count] => 240
            [customerid] => 34
        )
)

1 个答案:

答案 0 :(得分:1)

我的想法是将subcustomerscustomers分组到临时关联数组中,并将parentIDID作为键。在我可以构建结果之后。

首先,我创建一个带有子客户端数据的临时数组。此数组包含按parentId(第一级)和调用类型(第二级)分组的调用:

[parentID] => Array
    (
        [1] => Array
            (
                [calls] => //calls of type 1
                [duration] => //duration of type 1
            )
        [2] => Array
            (
                [calls] => //calls of type 2
                [duration] => //duration of type 2
            )
    )

这里是代码:

$tempS = array();

foreach($subcustomers as $subcustomer) {
    $parentId = $subcustomer['parentID'];
    $calls    = $subcustomer['calls'];
    $type     = $subcustomer['type'];
    $duration = $subcustomer['duration'];

    //if id/type is insered yet
    if(array_key_exists($parentId, $tempS) && array_key_exists($type, $tempS[$parentId])) {
        $tempS[$parentId][$type]['calls'] += $calls;
        $tempS[$parentId][$type]['duration'] += $duration;
    } else {
        $tempS[$parentId][$type]['calls'] = $calls;
        $tempS[$parentId][$type]['duration'] = $duration;
    }    
}

现在我用客户数据创建第二个临时数组。这个数组的结构是这样的:

[id] => Array
    (
        [name] => 'Telekom'
        [parentID] => 80
        [calls] => Array
            (
                [1] => //calls of type 1
                [2] => //calls of type 2
            )
        [duration] => Array
            (
                [1] => //duration of type 1
                [2] => //duration of type 2
            )
    )

这里是代码:

$tempC = array();

foreach($customers as $customer) {
    $id       = $customer['id'];
    $name     = $customer['name'];
    $parentId = $customer['parentID'];
    $calls    = $customer['calls'];
    $type     = $customer['type'];
    $duration = $customer['duration'];

    //if id/type is insered yet
    if(array_key_exists($id, $tempC) && array_key_exists('calls', $tempC[$id]) && array_key_exists($type, $tempC[$id]['calls'])) {
        if($calls!=null){
            $tempC[$id]['calls'][$type] += $calls;
            $tempC[$id]['duration'][$type] += $duration;
        }
    } else {
        if($calls!=null){
            $tempC[$id]['calls'][$type] = $calls;
            $tempC[$id]['duration'][$type] = $duration;
        }
        $tempC[$id]['name'] = $name;
        $tempC[$id]['parentID'] = $parentId;
    }
}

即使存储过程返回的集合中存在重复行,也会正确计算临时数组。请参阅上面的示例:

| id |   name  | parentID | calls | type | duration |
+----+---------+----------+-------+------+----------+
|  8 | Telekom |    80    |  100  |   1  |     3150 | 
|  8 | Telekom |    80    |   10  |   1  |      250 |

请注意,在这种情况下,将完成相同类型(110)和秒数(3400)的调用之和。

此时我可以计算结果数组:

$result = array();

foreach($tempC as $id => $customer) {

    $type1 = 1; $type2 = 2;
    $type1label = "Inbound Calls";
    $type2label = "Outbound Calls";

    $type1Call = 0;
    $type2Call = 0;
    $type1Duration = 0;
    $type2Duration = 0;

    if(array_key_exists('calls', $customer) && array_key_exists($type1, $customer['calls'])) {
        $type1Call += $customer['calls'][$type1];
        $type1Duration += $customer['duration'][$type1];
    }
    if(array_key_exists($id, $tempS) && array_key_exists($type1, $tempS[$id])) {
        $type1Call += $tempS[$id][$type1]['calls'];
        $type1Duration += $tempS[$id][$type1]['duration'];
    }
    if($type1Call>0) {
        $result[] = [
            'name' => $customer['name'],
            'label' => $type1label,
            'count' => $type1Call,
            'mins' => ceil($type1Duration / 60),
            'customerid' => $id
        ];
    }

    if(array_key_exists('calls', $customer) && array_key_exists($type2, $customer['calls'])) {
        $type2Call += $customer['calls'][$type2];
        $type2Duration += $customer['duration'][$type2];
    }
    if(array_key_exists($id, $tempS) && array_key_exists($type2, $tempS[$id])) {
        $type2Call += $tempS[$id][$type2];
        $type2Duration += $tempS[$id][$type2]['duration'];
    }
    if($type2Call>0) {
        $result[] = [
            'name' => $customer['name'],
            'label' => $type2label,
            'count' => $type2Call,
            'mins' => ceil($type2Duration / 60),
            'customerid' => $id
        ];
    }   
}

请注意,在计算结果之前,您可以在uasort()上使用$tempC方法来获取按客户订购的名称结果。