PHP + MySQL: поиск общего значения путем рекурсии через родительские дочерние группы mySQL - PullRequest
1 голос
/ 01 ноября 2010

У меня есть таблица MySQL, подобная этой:

Папки

[id] [name] [parent_id]
1    fruits  0
2    orange  1
3    lemon   2
4    steak   0

Проекты

[id] [name]     [parent_id]   [hours]
1    project1    1            3
2    project2    2            4
3    project3    3            6
4    project4    4            7

В основномпроекты могут находиться в разных папках.parent_id проектов - это идентификатор папки.Папки могут иметь подпапки, а проекты могут находиться в подпапках.Количество вложенных папок не ограничено.

Результат, который я хотел бы получить, - найти общее количество часов в папке и во всех ее подпапках.Таким образом, мы в основном проходим через папку и находим все дочерние папки в этой папке (и продолжаем делать это, пока она не достигнет самого глубокого уровня) и добавляем все часы для всех проектов в каждой из этих подпапок, чтобы получить общее количество часов.Думайте об этом как о базе данных задач или проектов, и я хочу рассчитать общее количество часов, потраченных на проект.

Есть ли способ сделать это через mySQL или PHP?

Пока у меня естьСледующая информация для MySQL.http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

И у меня есть эта функция PHP, но проблема в том, что я не знаю, как суммировать результаты.Я не знаю, как добавить массив в рекурсивную функцию.Возможно, в любом случае это неправильно, но я подумал, что просто выброслю это.

function categoryChild($id) {
    $s = "SELECT id FROM folders WHERE parent_id = $id";
    $r = mysql_query($s);
    $children = array();
    $hours = array();
    if(mysql_num_rows($r) > 0) {
        # It has children, let's get them.
        while($row = mysql_fetch_array($r)) {
            # Add the child to the list of children, and get its subchildren
            $ee['id'] = categoryChild($row['id']);
            $newid = $row['id'];
            $sql = "SELECT SUM(b.hours) as totalhours
            FROM folders a
            INNER JOIN projects b ON b.folder_id = a.id
            WHERE a.id = '$newid'";
            $result = mysql_query($sql);
            $children['hours'] = $row['totalhours'];

            }
        } 
        $s1 = "SELECT sum(hours) as totalhours FROM projects WHERE folder_id = $id";
        $r1 = mysql_query($s1);
        if(mysql_num_rows($r1) > 0) {
            while($row3 = mysql_fetch_array($r1)) {
            $children['hours'] = $row3['totalhours'];
            }
        }

    $data = $data['hours'];
    return $data;
}

Ответы [ 2 ]

1 голос
/ 03 ноября 2010

Это было тяжело ... но я думаю, что наконец-то решил это.

$totalhours = getSubfolders($id);
$totalhours = findTotalHours($totalhours,$id);


function findTotalHours($array,$id) {
 global $db, $user_id;
 $array = array_keys_multi($array);
 $array[] = $id; // i wanted to get all projects under starting folder
 $totalhours = implode(',',$array);
 $sql = "SELECT SUM(hours) AS totalhours FROM projects WHERE folder_id IN ($totalhours)";
 $row = $db->query_first($sql); 
 return $row['totalhours'];
}

function getSubfolders ($id) { //http://stackoverflow.com/questions/2398402/recursive-function-to-get-all-the-child-categories
    $s = "SELECT id FROM folders WHERE parent_id = $id";
    $r = mysql_query($s);
    $children = array();
    if(mysql_num_rows($r) > 0) {
        # It has children, let's get them.
        while($row = mysql_fetch_array($r)) {
            # Add the child to the list of children, and get its subchildren
            $children[$row['id']] = getSubfolders($row['id']);
        }
    }
    return $children;
}

function array_keys_multi(array $array) //http://codeaid.net/php/extract-all-keys-from-a-multidimensional-array
{
 $keys = array();
 foreach ($array as $key => $value) {
  $keys[] = $key;
  if (is_array($array[$key])) {
   $keys = array_merge($keys, array_keys_multi($array[$key]));
  }
 }
 return $keys;
}
0 голосов
/ 01 ноября 2010

Я не уверен, что слежу за тем, что вы пытаетесь сделать со своим кодом, но вот скелет того, как я бы организовал его.

function getTotalHours( $id) {

  $sum = getHoursOnProject( $id);
  foreach( getChildIds( $id) as $childId) {
    $sum += getTotalHours( $childId);
  }
  return $sum;
}

function getChildIds( $id) {
  $query = "SELECT id FROM folders WHERE parent_id = $id";
  ...
  return $childIdArray;
}

function getHoursOnProject( $id) {
  $query = "SELECT sum(hours) as totalhours FROM projects WHERE folder_id = $id";
  ...
  return $hours;
}
...