仅在一个 SQL 查询中检索所有类别、子类别、子子类别等的完整列表
Posted
技术标签:
【中文标题】仅在一个 SQL 查询中检索所有类别、子类别、子子类别等的完整列表【英文标题】:Retrieve a complete list of all Categories, Sub Categories, Sub Sub Categories, etc. in only one SQL query 【发布时间】:2009-07-23 06:03:26 【问题描述】:我在 mysql 中有以下表结构和数据
CatID CatName ParentCatID
-------------------------------
1 Shirts NULL
2 Short Sleev 1
3 Long Sleev 1
4 Collarless 2
5 Collar 2
6 Collarless 3
7 Collar 3
8 Square Cut 4
9 Round Cut 4
10 Square Cut 6
11 Round Cut 6
我想要的返回数据是这样的:
Shirts > Short Sleev
Shirts > Long Sleev
Shirts > Short Sleev > Collarless
Shirts > Short Sleev > Collar
Shirts > Long Sleev > Collarless
Shirts > Long Sleev > Collar
Shirts > Short Sleev > Collarless > Square Cut
Shirts > Short Sleev > Collarless > Round Cut
Shirts > Short Sleev > Collar > Square Cut
Shirts > Short Sleev > Collar > Round Cut
我们如何在 MySQL 中使用一个 SQL 查询来获取这些数据?
【问题讨论】:
您知道您的数据库中有拼写错误吗?它是“袖子”和“颜色”。 嗯,我看到我拼错了 Sleeve and Collar 和 Collarless。感谢您指出。未更正。 【参考方案1】:不是一个真正的答案,但我过去在 php 中使用的一个肮脏的修复是这样的:
$categories = array();
$sql = "SELECT CatID, CatName, ParentCatID FROM TableName";
$res = mysql_query($sql);
while ($row = mysql_fetch_assoc($res))
$parent = intval($row['ParentCatId']);
if (!isset($categories[$parent]))
$categories[$parent] = array();
$categories[$parent][] = $row;
这将为您提供一系列类别和子类别,您可以使用递归函数对其进行迭代。比如:
function build_categories($parent, $categories)
if (isset($categories[$parent]) && count($categories[$parent]))
echo '<ul>';
foreach ($categories[$parent] as $category)
echo '<li><a href="#">' . $category['CatName'] . '</a>';
echo build_categories($category['id'], $categories);
echo '</li>';
echo '</ul>';
$menu = build_categories(0, $categories);
【讨论】:
【参考方案2】:查看Managing Hierarchical Data in MySQL 和Storing Hierarchical Data in a Database。
【讨论】:
感谢您的链接。我会检查出来的。 您能否将这些文章的精髓添加到您的答案中?在目前的形式中,它只不过是一条评论。【参考方案3】:我需要它作为具有层次结构的下拉列表。所以我使用了上面的代码并做了一些更改。结果符合我的要求。我想把这个分享给你。
$category_string = "";
function build_categories_options($parent, $categories, $level)
global $category_string;
if (isset($categories[$parent]) && count($categories[$parent]))
$level .= " - ";
foreach ($categories[$parent] as $category)
$opt_value = substr($level.$category['CatName'],3);
$category_string .= '<option value="'.$category['CatID'].'">'.$opt_value.'</option>';
build_categories_options($category['CatID'], $categories, $level);
$level = substr($level, -3);
return $category_string;
$category_options = build_categories_options(0, $categories, '');
$category_options = '<select name="sel_category" id="sel_category">'.$category_options.'</select>';
然后使用 echo 语句在页面的任何位置打印。
<?php echo $category_options; ?>
【讨论】:
感谢您提供此示例。我已经实现了递归算法来检索包含所有子类别的类别列表,但我希望在数据库级别执行此操作,以便 MySQL 将在一个简单的查询中返回列表,或者我们可以定义一个返回完整列表的视图。 【参考方案4】:我认为 MySQL 不支持树状结构(例如,与 Oracle 相反)。
如果你知道你的树的最大深度,你可以用连接做一些事情......如果你不知道,那就更难了。
例如,您可以查看文章Managing Hierarchical Data in MySQL。
如果您的表格中只有几行,一个可能好的解决方案是只使用“select *
”,并在 PHP 中处理所有这些。
【讨论】:
这正是我们目前正在做的事情。但是如果可能的话,我希望自己免于维护这些额外的 PHP 代码的麻烦。以上是关于仅在一个 SQL 查询中检索所有类别、子类别、子子类别等的完整列表的主要内容,如果未能解决你的问题,请参考以下文章