MySQL统计所有孩子,无论有多少孩子

时间:2011-10-07 03:32:16

标签: php mysql sql loops smf

我正在开发一个简单的系统,每个类别都有无限的类别和项目。例如,类别内的类别等(类别1 - >类别2 - >类别3)可以包含所有项目。我想显示每个类别及其所有子类别的总项目。我试图找出一个循环来做到这一点,但基本上我很快。我在PHP / MySQL中构建。我的类别表模式是类别(id,id_parent)id是自动增量,id_parent是它是否驻留在另一个类别内(默认为0)。我的项目架构是项目(id,id_category)。显然还有其他专栏,但这些是我认为唯一重要的专栏。有人可以帮我开发一个循环结构,为他们所在的类别提供一定数量的项目(计算所有子类别项目)。这是我开始的,虽然我觉得这是非常非常错误的。

function CountChildDownloads($id_category)
{
global $smcFunc;
$x = array();
$total = 0;

$request = $smcFunc['db_query']('', '
    SELECT COUNT(*) AS items FROM {db_prefix}xld_downloads
    WHERE id_category = '.$id_category.''
);

$total += $request['items'];

$request = $smcFunc['db_query']('', '
    SELECT id FROM {db_prefix}xld_categories
    WHERE id_parent = '.$id_category.''
);

if($smcFunc['db_num_rows']($request) > 0)  {
    while($row = $smcFunc['db_fetch_assoc']($request)) {
        $x[] = $row['id'];
    }
}

foreach ($x as $id)
{
    $y = array();
    $z = 0;

    $request = $smcFunc['db_query']('', '
        SELECT COUNT(*) AS items FROM {db_prefix}xld_downloads
        WHERE id_category = '.$id.''
    );

    $z += $request['items'];

    $request = $smcFunc['db_query']('', '
        SELECT id FROM {db_prefix}xld_categories
        WHERE id_parent = '.$id.''
    );

    if($smcFunc['db_num_rows']($request) > 0)  {
        while($row = $smcFunc['db_fetch_assoc']($request)) {
            $y[] = $row['id'];
        }
    }

    while (count($y) > 0)
    {
        $id_y = $y[0];

        $request = $smcFunc['db_query']('', '
            SELECT id FROM {db_prefix}xld_categories
            WHERE id_parent = '.$id_y.''
        );

        if($smcFunc['db_num_rows']($request) > 0)  {
            while($row = $smcFunc['db_fetch_assoc']($request)) {
                $y[] = $row['id'];
            }
        }

        $request = $smcFunc['db_query']('', '
            SELECT COUNT(*) AS items FROM {db_prefix}xld_downloads
            WHERE id_category = '.$id_y.''
        );

        $z += $request['items'];

        unset($y[0]);
        array_values($y);
    }

    $total += $z;
}

return $total;
}

$ smcFunc只是进行查询的系统方式。这是一个MySQL后端。

工作功能(如果不使用SMF,将需要更新到标准的MySQL调用)感谢Lucas。

function CountChildDownloads($id_category)
{
global $smcFunc;
$x = array();
$total = array();
$total['downloads'] = 0;
$total['views'] = 0;

$request = $smcFunc['db_query']('', '
    SELECT views FROM {db_prefix}xld_downloads
    WHERE id_category = '.$id_category.''
);

if($smcFunc['db_num_rows']($request) > 0)  {
    while($row = $smcFunc['db_fetch_assoc']($request)) {
        $total['downloads']++;
        $total['views'] += $row['views'];
    }
}

$request = $smcFunc['db_query']('', '
    SELECT id FROM {db_prefix}xld_categories
    WHERE id_parent = '.$id_category.''
);

if($smcFunc['db_num_rows']($request) > 0)  {
    while($row = $smcFunc['db_fetch_assoc']($request)) {
        $x[] = $row['id'];
    }
}

foreach ($x as $id)
{
    $y = array();
    $z = 0;
    $w = 0;

    $request = $smcFunc['db_query']('', '
        SELECT views FROM {db_prefix}xld_downloads
        WHERE id_category = '.$id.''
    );

    if($smcFunc['db_num_rows']($request) > 0)  {
        while($row = $smcFunc['db_fetch_assoc']($request)) {
            $z++;
            $w += $row['views'];
        }
    }

    $request = $smcFunc['db_query']('', '
        SELECT id FROM {db_prefix}xld_categories
        WHERE id_parent = '.$id.''
    );

    if($smcFunc['db_num_rows']($request) > 0)  {
        while($row = $smcFunc['db_fetch_assoc']($request)) {
            $y[] = $row['id'];
        }
    }

    while (count($y) > 0)
    {
        $id_y = $y[0];

        if (!empty($id_y))
        {
            $request = $smcFunc['db_query']('', '
                SELECT id FROM {db_prefix}xld_categories
                WHERE id_parent = {int:id_parent}',
                array(
                    'id_parent' => $id_y,
                )
            );

            if($smcFunc['db_num_rows']($request) > 0)  {
                while($row = $smcFunc['db_fetch_assoc']($request)) {
                    $y[] = $row['id'];
                }
            }

            $request = $smcFunc['db_query']('', '
                SELECT views FROM {db_prefix}xld_downloads
                WHERE id_category = {int:id_category}',
                array(
                    'id_category' => $id_y,
                )
            );

            if($smcFunc['db_num_rows']($request) > 0)  {
                while($row = $smcFunc['db_fetch_assoc']($request)) {
                    $z++;
                    $w += $row['views'];
                }
            }
        }

        unset($y[0]);
        $y = array_values($y);

    }

    $total['downloads'] += $z;
    $total['views'] += $w;
}

return $total;
}

1 个答案:

答案 0 :(得分:1)

(嵌套循环/查询有很多种方法..结构改变的想法是有一个单独的表,列出每个类别的所有子项..并确保它不仅有直接的孩子,它也有子孩子和子孩子......比如1有孩子2,有孩子3,有孩子3,有孩子3,有孩子5,有孩子5等..)但是,对于现在情况..

一个循环结构可能是:

启动结果集。 || 查询parent = 0的所有类别ID。||将每个添加到数组(X)。 || 关闭结果集。

对于数组(X)中的每个id:

  • 建立一个新的计数变量(z)。
  • 建立一个新的子ID数组(Y)。

  • 启动结果集。 || 查询计数*为category = current id x ||的所有项目 添加到计数变量(z)|| 关闭结果集。

  • 启动结果集。 || 查询所有类别ID,其中parent = current id x || 将所有内容添加到子ID数组(Y)。 || 关闭结果集。

  • ,而子阵列(Y)长度> 0

    • 类别ID y =数组中的第一项(Y)

    • 启动结果集。 || 查询parent = current id y的所有类别ID。 || 将所有内容添加到子ID数组(Y)。 || 关闭结果集。

    • 启动结果集。 || 查询计数*为category = current id y ||的所有项目 添加到计数变量(z)|| 关闭结果集。

    • 从数组中删除第一项(Y)

  • 继续循环播放

  • 此时你有类别id x的最终项目数(z)...用它做某事,然后继续for循环

结束循环