postgresql — группировка похожих записей с переполнением стека

Мне нужна помощь в написании логики скрипта php, который сортирует данные в определенный формат …

Во-первых, сценарий должен пройти через каждое значение s1 и пропинговать конечную точку, чтобы получить значения ml (более похожие), которые фактически ссылаются на другие записи s1. Это легкая часть! данные возвращаются вот так;

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();

}

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

}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]