MySQL 计算所有子节点,无论有多少个
我正在开发一个简单的系统,该系统具有无限的类别和每个类别中的项目。例如,类别内可能有类别等(类别 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
(嵌套循环/查询有多种方法。结构更改的想法是有一个单独的表,列出每个类别的所有子项。并确保它不仅具有直接子项,还具有子项-孩子和子子孩子...比如1有孩子2,2有孩子3,1有孩子3,3有孩子5,1有孩子5..等等..)但是,对于目前的情况..
一个循环结构可以be :
开始结果集。 ||
查询父级 = 0 的所有类别 ID。 ||将每个添加到数组 (X)。 ||
关闭结果集。
对于数组(X)中的每个id:
建立一个新的子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 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