【问题标题】:PHP + MySQL: Finding total of values by recursing through mySQL parent children groupsPHP + MySQL:通过 mySQL 父子组递归查找总值
【发布时间】:2010-11-01 17:42:30
【问题描述】:

我有一个这样的 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 是文件夹的 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;
}

【问题讨论】:

  • 您是否按照您那里的 mysql 链接中所述使用嵌套集进行了调查?如果您有一个读取繁重的应用程序,嵌套集模型将是一个很好的选择,但如果与读取相比,您必须执行大量写入操作,则它会失去其有效性。
  • 我宁愿使用闭包表。请参阅Bill Karwin's slides,它包含一个用于邻接模型的深度树搜索示例,以及您当前设置的可能替代方案。

标签: php mysql recursion


【解决方案1】:

这很艰难......但我想我终于解决了这个问题。

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

【讨论】:

    【解决方案2】:

    我不确定我是否遵循您对代码的处理方式,但这里是我将如何组织它的框架。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-01
      • 2018-12-27
      • 1970-01-01
      • 2022-01-20
      • 2012-10-18
      • 2021-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多