我有一个categories
表设置,如:
ID CatName CatParent
1 Websites NULL
2 Recipes NULL
3 Programming 1
4 Helpful 3
5 Useless 3
6 Desserts 2
如果我有类别ID,我想查询数据库,按祖先的顺序选择类别和所有父母。每个类别都有一个CatParent
,它是父项,如果没有父项,则为NULL
。
因此,例如,如果我的类别ID为4,我想要一个返回的查询:
array('4','3','1'); // Helpful > Programming > Websites
或者,如果我的类别ID为6:
array('6','2'); // Desserts > Recipes
或类别ID为1:
array('1');
我如何构建此查询?
答案 0 :(得分:3)
您可以使用left join
来获取父类别,但这只有在有限制时才有意义。对于无限的类别深度,我会用PHP做。不过,这是一个示例查询:
select c1.id, c2.id, c3.id
from categories c1
left join categories c2 on c2.id = c1.catparent
left join categories c3 on c3.id = c2.catparent
where c1.id = 4
如果类别4只有一个父级,则最后一个ID(c3.id)将为NULL。您必须在代码中考虑这一点。
答案 1 :(得分:1)
要实现此目的,您可以创建一个过程。如果使用phpmyadmin,您可以转到数据库,转到SQL并插入以下内容:
DELIMITER //
CREATE PROCEDURE get_parents(IN cid int)
BEGIN
DECLARE child_id int DEFAULT 0;
DECLARE prev_id int DEFAULT cid;
DECLARE loopran int DEFAULT 0;
SELECT CatParent into child_id
FROM categories WHERE ID=cid ;
create TEMPORARY table IF NOT EXISTS temp_table as (select * from categories where 1=0);
truncate table temp_table;
WHILE child_id <> 0 OR loopran <> 1 DO
SET loopran = 1;
insert into temp_table select * from categories WHERE ID=prev_id;
SET prev_id = child_id;
SET child_id=0;
SELECT CatParent into child_id
FROM categories WHERE ID=prev_id;
END WHILE;
select * from temp_table;
END //
该过程创建一个临时表来存储数据。变量loopran,只是为了确保即使该类别没有子节点,也会返回父节点。
接下来,检索结果:
$id = 5;
$result = "
CALL get_parents($id)
"; // Call the procedure just like as if it were a php function
$query = mysqli_query($conn, $result) or die(mysqli_error($conn));
$x = 0;
while ($row = mysqli_fetch_array($query)) {
if ($x > 0) echo ", ";
echo $row['ID'] . " | " . $row['CatParent'];
$x++;
}
$id = 4
返回:4 | 3, 3 | 1
$id = 6
返回:6 | 2
$id = 1
返回:1 |
$id = 9
什么都不返回(如果该行当然不存在。)
有一个很大的问题。也就是说,如果你最终进入一个循环,最终指向循环中的前一个id,它将导致无限循环。要解决此问题,您必须退出while循环,条件是它尝试添加已添加的内容。但我认为这绝不会自然而然地发生。 (当然,取决于您使用它的方式以及如何设置ParentID)
来源&amp;来自:@Meherzad - https://stackoverflow.com/a/16514403/2506641