用php分组类似的记录

时间:2015-01-21 09:34:49

标签: php postgresql loops grouping records

我需要帮助编写php脚本的逻辑,将数据分类为某种格式......

首先,脚本需要遍历每个s1值并ping一个端点以获取实际引用其他s1记录的ml值(更像)。这是简单的部分!像这样返回数据;

Table 1
s1  |   ml
----------
1   |   -
2   |   3,4    
3   |   2,8,9
4   |   -
5   |   2
6   |   1
7   |   10
8   |   -
9   |   -
10  |   -

条件1:正如您所看到的,端点返回s1值的数据,告诉其他s1记录与其他记录类似,但ml的方向并不总是双向的。有时候,比如当s1 = 6时,ml值为1,但是当s1 = 1时,没有ml值。

条件2:再次只是为了解释ml记录,看上下s1 = 5(上图)和s1 = 2 + rec = 5(下图),这个脚本需要实现已经有一个s1记录它的值,它应该被添加到那里。

条件3:请注意当s1 = 2时,ml = 3这是如何存储的,但是当s1 = 3时,ml = 2这会被忽略,因为我们有反向记录。

我基本上希望将所有数据匹配到1个排序的“配置文件”中,因此它最终会以下面的格式存储,我将存储在另一个“已排序”记录的数据库表中。

Table 2
s1  |   rec
----------
2   |   3
2   |   4
2   |   8
2   |   9
2   |   9
2   |   5
6   |   1
7   |   10

这已经绞尽脑汁了好几天,我需要一些有效的东西,因为它最终将处理数百万条记录,我确信有一个简单的解决方案,但我无法想象如何启动它

我尝试了以下内容,但是我被困住了,不知道该怎么走;

public function getrelated($id='', $t=''){

    if($id != ""){
    $get = Easytest::where('s1','=',$id)->get();

        if(count($get) > 0){
            $ret= array();
            foreach($get as $go){
                    $v = explode(",", $go->s2);

                    foreach ($v as $e) {
                        if($e != $t){
                            $ret[$e] = $this->getrelated($e, $id);
                        }
                    }
                }
                if(count($ret) > 0){
                    return $ret;
                }else{
                    return "";
                }

        }else{
                return $id;
        }
     }else{
        return "";
     }

     }

public function easytest(){
    ob_start();
    $a = array(
                array("s1"=>1,"s2"=>implode(",",array()).""),
                array("s1"=>2,"s2"=>implode(",",array(3,4)).","),
                array("s1"=>3,"s2"=>implode(",",array(2,8,9)).","),
                array("s1"=>4,"s2"=>implode(",",array()).""),
                array("s1"=>5,"s2"=>implode(",",array(2)).","),
                array("s1"=>6,"s2"=>implode(",",array(1)).","),
                array("s1"=>7,"s2"=>implode(",",array(10)).","),
                array("s1"=>8,"s2"=>implode(",",array()).""),
                array("s1"=>9,"s2"=>implode(",",array()).""),
                array("s1"=>10,"s2"=>implode(",",array()).""),
                array("s1"=>11,"s2"=>implode(",",array(12)).","),
                array("s1"=>12,"s2"=>implode(",",array(2)).",")
                );

    //return Easytest::insert($a);

    $records = Easytest::all();

    foreach ($records as $record) {

        $id = $record->s1;
        echo "ROW: ".$id." > ";
        $record->s2 = ltrim($record->s2,",");
        $ml = explode(",",$record->s2);
        if(count($ml) >= 1){
            foreach ($ml as $t) {

                echo "RESULT: ".$t." -".print_r($this->getrelated($t, $id), true);
                echo ",\n";

            }
        }
        echo " <br><br>\n\n";

    }

    return ob_get_clean();

}

1 个答案:

答案 0 :(得分:0)

好的,所以我最终解决了这个......基本上这是下面的代码; 改进欢迎:))

您需要像这样调用函数

related(array('searched'=>array(),'tosearch'=>array(13)));

功能:

public function related($input){


    $searched = $input['searched'];

    $ar = array();
    $bits = array();

    if(count($input['tosearch']) != 0){

        $get = Easytest::orWhere(function($query) use ($input)
                        {
                            foreach ($input['tosearch'] as $k=>$v) {
                                    $query->orWhere('s2', 'LIKE', '%,'.$v.',%')->orWhere('s1', '=', $v);
                                }                      
                        })
            ->orderBy('s1', 'ASC')->get();

            foreach ($input['tosearch'] as $k=>$v) {
                                unset($input['tosearch'][$k]);
                                $input['searched'][$v] = $v;
                }


            foreach ($get as $result) {

                $thesebits = explode(",", trim($result->s2,","));
                foreach ($thesebits as $smallbit) {
                    if($smallbit != ""){
                    $bits[] = $smallbit;
                    }
                }

                $bits[] = $result->s1;
                $bits = array_unique($bits);

                foreach ($bits as $k=>$v) {
                        if(($key = array_search($v, $input['searched'])) == false) {
                                $input['tosearch'][$v] = $v; 
                        }else{
                            unset($input['tosearch'][$v]);
                        }

                }

                $input['tosearch'] = array_unique($input['tosearch']);

            }
            return $this->related($input);
    }else{
        return $input;
    }

}