我有MySQL类别表如下。其中parent
字段指示父类别的ID
,hassub
字段指示类别是否具有子类别。 (我使用PHP作为基础。)
************************************
| ID | parent | name | hassub |
************************************
| 1 | 0 | Nature | 1 |
| 2 | 1 | foo | 0 |
| 3 | 1 | bar | 1 |
| 4 | 3 | bar1 | 0 |
| 5 | 0 | Anime | 0 |
************************************
现在以分层格式获取所有类别,有没有办法在尽可能少的MySQL查询中执行此操作?
- 主要分类1
- 子类别1
- 子类别 2
- 子类别3
- 主要类别2
- 主要类别3
- 子类别1
- 子类别 2
我现在正在做的是获取parent = 0
的所有行,然后查询每一行以获取它的子类别。
答案 0 :(得分:3)
这是在文本编辑器中手写的...我没有一个开发环境,所以如果这只是错误或包含错别字,那么appologies。
但不管我认为这个想法是否清晰/健全。
$sql
将是:
SELECT
parent.id as parentid,
parent.[name] as parentname,
child.[name] as childname
FROM
category child
left join category parent -- Can't exclude parents with no children, else they won't appear in the list!
on child.parent = parent.id
ORDER BY
parentid
然后PHP将是:
function categoryLevels(){
$bullet = "*"; // You can specify your HTML/CSS :-)
$indent = " "; // You can specify your HTML/CSS :-)
$sql = "_as above_";
$query = mysql_query($sql);
$lastParentId = 0;
while($row = mysql_fetch_array($query)){
$parentId = $row['parentid']
if ($parentId != 0) {
if ($parentId != $lastParentId) {
echo $bullet . $row['parentname']
$lastParentId = $parentId;
}
if (!is_null($row['childname']) { // this line is psuedo-code! - don't know the php equiv for is_null, sorry.
echo $indent . $bullet . $row['childname'];
}
}
}
}
这个要点基本上是:
编辑它不那么复杂(也更快)。现在,SQL只是完全排除父行,而不是用PHP中的IF
语句排除它们。
答案 1 :(得分:0)
您可以使用递归方法
function getSubCategories($parent_id = 0){
$sql = "select col1, col2,... from table_name where parentt_id = ".$parent_id;
$query = mysql_query($sql);
while($row = mysql_fetch_array($query)){
echo $row['category_name'];
getSubCategories($row['category_id']);
}
}
getSubCategories();
这将以分层格式打印所有类别。您可以使用这种方式生成分层类别格式。
答案 2 :(得分:0)
您可以加入数据(提供您知道的深度)。
例如:
CREATE TABLE`test` (
`id` INT(11) unsigned NOT NULL AUTO_INCREMENT,
`parent` INT(10) unsigned NOT NULL DEFAULT '0',
`name` VARCHAR(50),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO test (id, parent, name) values
(1, 0, 'Nature'),
(2, 1, 'Foo'),
(3, 1, 'Bar'),
(4, 3, 'Bar1'),
(5, 0, 'Anime');
我们知道有两个级别,因此只需要一个连接 - 每个级别都需要连接,这是adjacancy list模型的许多缺点之一。
SELECT a.name AS 'Level 1', b.name AS 'Level 2' FROM test AS a
LEFT JOIN test AS b
ON b.parent = a.id
WHERE a.parent = 0
这会给出输出:
+---------+---------+
| LEVEL 1 | LEVEL 2 |
---------------------
| Nature | Foo |
| Nature | Bar |
| Anime | (null) |
+---------+---------+
从此输出中,您可以遍历数组并填充项目符号列表。