MySQL 计算所有子节点,无论有多少个

发布于 2024-12-08 20:45:17 字数 4847 浏览 0 评论 0原文

我正在开发一个简单的系统,该系统具有无限的类别和每个类别中的项目。例如,类别内可能有类别等(类别 1 -> 类别 2 -> 类别 3),所有类别都包含项目。我想显示每个类别及其所有子类别的总项目。我正在尝试找出一个循环来做到这一点,但基本上还不够。我正在使用 PHP/MySQL 进行构建。我的类别表模式是category(id, id_parent) id是自动递增的,id_parent是它是否驻留在另一个类别中(默认为0)。我的项目架构是 items(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;
}

I am developing a simple system that has unlimited categories and items in each category. For instance there could be categories inside categories etc (Category 1 -> Category 2 -> Category 3) all containing items. I want to display the total items for each category and ALL of their subcategories. I am trying to figure out a loop to do this but basically am coming up short. I am building in PHP/MySQL. My category table schema is category(id, id_parent) id being auto increment and id_parent being whether it resides inside another category (0 is default). My items schema is items(id, id_category). Obviously there are other columns but these are the only ones that matter I believe. Can someone please help me develop a loop structure come up with a total amount of items for the category they are in (counting all subcategories items as well). Here is what I started although I feel it is very, very wrong.

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

The $smcFunc is just the systems way to do queries. It is a MySQL backend.

Working function (will need to update to standard MySQL calls if not using SMF) Thanks 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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

去了角落 2024-12-15 20:45:17

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

一个循环结构可以be :

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

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

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

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

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

  • 而子数组(Y)长度> 0

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

    • 启动结果集。 ||
      查询所有类别 id,其中父级 = 当前 id y。 ||
      将所有内容添加到子 id 数组 (Y)。 ||
      关闭结果集。

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

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

  • 继续 while 循环

  • 此时,您得到了最终的项目数 (z ) for 类别 id x... 对其进行处理,然后继续 for 循环

结束 for 循环

(There are numerous approaches to nested loops / queries.. a structure change idea would be to have a separate table that lists all the children of each category.. and make sure that it not only has the immediate children, it also has the sub-children and sub-sub-children... like 1 has child 2, 2 has child 3, 1 has child 3, 3 has child 5, 1 has child 5.. etc..) BUT, for the current situation..

One loop structure could be :

Start resultset. ||
Query for all category ids where parent = 0. || Add each to array (X). ||
Close resultset.

For each id in array (X):

  • Establish a new counting variable (z).
  • Establish a new child id array (Y).

  • Start resultset. ||
    Query count * for all items with category = current id x ||
    Add to counting variable (z) ||
    Close resultset.

  • Start resultset. ||
    Query for all category ids where parent = current id x ||
    Add all to child id array (Y). ||
    Close resultset.

  • while child array (Y) length > 0

    • category id y = first item in array (Y)

    • Start resultset. ||
      Query for all category ids where parent = current id y. ||
      Add all to child id array (Y). ||
      Close resultset.

    • Start resultset. ||
      Query count * for all items with category = current id y ||
      Add to counting variable (z) ||
      Close resultset.

    • remove first item from array (Y)

  • continue while loop

  • At this point you have the final item count (z) for category id x... do something with it, then continue with the for loop

End for loop

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文