сложная выборка из трех таблиц

krafty

new Exception
сложная выборка из трех таблиц

t1 (id,f1)
t2 (id,f2)
И таблица связи между t1 и t2 (многие ко многим)
t3(id1,id2)

Результирующая выборка должна иметь вид

PHP:
f1  |   f2
----|----------
A   |   a,c,d
B   |   a,b
C   |   c,e
Т.е. нужно выбрать для каждого элемента f1 из t1 все соответствующие ему элементы f2 из t2. Эти соответствия задаются в таблице связей t3.
[sql]
SELECT * FROM objects LEFT JOIN permiss_obj ON id_obj=id
[/sql]
выдает такой результат
PHP:
f1  |   f2
----|----------
A   |   a
A   |   с
A   |   d
B   |   a
B   |   b
C   |   c
и так далее.... только вместо значений f2 - поле id из t3.
Такой результат сложно обрабатывать для конечного вывода. Можно одним запросам добиться, что бы в mysql_fetch_* содержался именно необходимый набор?
 

Profic

just Profic (PHP5 BetaTeam)
Одна переменная, одно условие + одна операция "сложно"?
Если таки сложно и позволяет муська, то смотреть в сторону GROUP_CONCAT().
 

krafty

new Exception
>Одна переменная, одно условие + одна операция
мне не кажется что все так просто
ну ум приходит только это:
PHP:
while ($f=mysql_fetch_array($res)) {
                   $mass['f1'][]=$f['f1'];
                   $mass['f2'][]=$f['id2'];
}
foreach ($mass as $k=>$v) {
     $temp=array();  
     while ($mass['script'][$k-1]==$mass['script'][$k])
         $temp[]=$mass['id'][$k-1];
     $final['f1'][]=$mass['script'][$k];
     $final['f2'][]=implode(', ',$temp);
}
этот бред нужно еще долго отлаживать
 

Gas

может по одной?
krafty
всё можно сформировть в первом цикле

но если mysql > 4.1 то GROUP_CONCAT самое оно.
 

krafty

new Exception
Gas
вообще-то MSSQL :(

если все в первом цикле, то как тогда обращаться к предыдущему элементу?
 

Gas

может по одной?
стоп, а почему тогда используешь?
while ($f=mysql_fetch_array($res)) {
как тогда обращаться к предыдущему элементу
формируй массив с ключами f1 и соответствующими значениями f2. Сразу. В одном цикле при получении данных из базы.
 

krafty

new Exception
PHP:
$prev=mysql_fetch_array($res);
while ($f=mysql_fetch_array($res)) {
  if ($prev==$f['f1'])
     $to_implode[]=$f['f2'];
  else {
    $to_implode=array();
    $mass[0][]=$prev;
    $mass[1][]=implode(',',$to_implode);
}
}
в таком духе?
 

Profic

just Profic (PHP5 BetaTeam)
PHP:
$last = -1;
while ($f = mysql_fetch_array($res)) {
    if (!count($mass) || $mass[$last]['f1'] != $f['f1']) {
        $mass[++$last]['f1'] = $f['f1'];
    }
    if (isset($mass[$last]['f2'])) {
        $mass[$last]['f2'] .= ', ';
    } else {
        $mass[$last]['f2'] = '';
    }
    $mass[$last]['f2'] .= $f['id2'];
}
И не нужно никаких дополнительных массивов.

А вот обращаться к MSSQL через функции доступа к MySQL и правда странно.
 

krafty

new Exception
>стоп, а почему тогда используешь?
с целью уменьшения оффтопа:) не хочу копаться в спец. функциях ms. может там че-то и есть подходящее

-~{}~ 18.11.05 21:51:

ребята!!! забудте про мелкомягкий сиквел!
 

Profic

just Profic (PHP5 BetaTeam)
или даже так:
PHP:
$last = -1;
while ($f = mysql_fetch_array($res)) { 
    if (!count($mass) || $mass[$last]['f1'] != $f['f1']) {
        if (count($mass)) {
            $mass[$last]['f2'] = implode(', ', $mass[$last]['f2']);
        }
        ++$last;
        $mass[$last]['f1'] = $f['f1']; 
        $mass[$last]['f2'] = array(); 
    } 
    $mass[$last]['f2'][] = $f['id2']; 
}
if (count($mass)) {
    $mass[$last]['f2'] = implode(', ', $mass[$last]['f2']);
}
 

krafty

new Exception
Profic
сенкс!

-~{}~ 21.11.05 08:51:

Два дня мучился!!! Вот это работает
PHP:
function query_mass($sql,$left_f,$right_f) {
  $res=mysql_query($sql);
  $last=0;         
  $f=mysql_fetch_array($res);
  $mass[$last][$right_f]=$f[$right_f];
  $mass[$last][$left_f]=$f[$left_f];
  while ($f=mysql_fetch_array($res)) {
    if ($mass[$last][$left_f]==$f[$left_f]) {
      $imp[]=$mass[$last][$right_f];
      $imp[]=$f[$right_f];
    }
    else {
      ++$last;   
    }    
    if (count($imp)>1) {
      $mass[$last][$right_f]=implode(',',$imp);
    }  
    else {
      $mass[$last][$right_f]=$f[$right_f];
    }
    $mass[$last][$left_f]=$f[$left_f];
    $imp=array();
  }
  return $mass;
}
 

kos

Новичок
Сегодня сделал что-то подобное, по моему можно гараздо проше
PHP:
while($res_var=mysql_fetch_array($res)){		
   if(!is_array($result[$res_var["f1"]]))
      $result[$res_var["f1"]]=$res_var["f2"];
   else
      $result[$res_var["f1"]]=$result[$res_var["f1"]].",".$res_var["f2"];
}
и работать должно быстрее
 

Gas

может по одной?
kos
только лучше не is_array, а [m]isset[/m] и есть такая конструкция .=

твой код не работает
Нормальный код, но тебе похоже нужно в каком-то другом формате.
 

krafty

new Exception
>Нормальный код
может быть, только не для моей задачи. Пусть сначала условие прочтет. На выходе нужен двухмерный массив
 

kos

Новичок
он работает, ну может нужно подправить, делает как описано в первом посте. Такой же результата дал бы GROUP_CONCAT
а одно, двух, трех мерный это уже дело третье
у меня вообще так
PHP:
while($res_var=mysql_fetch_array($res,MYSQL_ASSOC)){
   if(!is_array($result[intval($res_var["id"])]))
      $result[intval($res_var["id"])]=array(param=>array(type=>$res_var["type"],master_id=>$res_var["master_id"],level=>$param["level"],module=>$module_id),value=>array(id=>$res_var["id"],$res_var["field"]=>$res_var["value"]));
    else
       $result[intval($res_var["id"])]["value"][$res_var["field"]]=$res_var["value"];			
}
 
Сверху