3

我有这样的邻接列表模式结构

在此处输入图像描述

通过这个查询

SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS';

得到这样的结果

在此处输入图像描述

但我想得到这样的结果,有什么选择吗

在此处输入图像描述

提前致谢

4

4 回答 4

1

不幸的是,使用当前设置很难计算一个类别的子类别数量。不仅菜单的深度受LEFT JOIN您添加的 's 数量的限制,而且也无法分辨哪些类别直接链接到超过一级深度的类别。

这个问题的一个很好的解决方案是nested set为你的菜单使用一个结构,你可以在这里阅读更多。更多解释如何在此处使用 mysql 执行此操作。

于 2012-05-08T08:18:28.770 回答
1

您将需要一个 UNION,我建议删除相应级别的条目重复项。此外,如果您打算像在 Web 应用程序中一样向用户展示,则无需包含“NULL”值......

select L1.Category_ID,
       L1.name, 
       "1" as HierarchyLevel, 
       count( L2.Category_ID ) as NextLevelCount
   from Category L1
        LEFT JOIN Category L2
           on L1.Category_ID = L2.Parent
   where L1.name = "ELECTRONICS"
   group by L1.Category_ID
UNION
select L2.Category_ID,
       L2.name, 
       "2" as HierarchyLevel,
       count( L3.Category_ID ) as NextLevelCount
   from Category L1
        JOIN Category L2
           on L1.Category_ID = L2.Parent
           LEFT JOIN Category L3
              on L2.Category_ID = L3.Parent
   where L1.name = "ELECTRONICS"
   group by L2.Category_ID
UNION
select L3.Category_ID,
       L3.name, 
       "3" as HierarchyLevel,
       count( L4.Category_ID ) as NextLevelCount
   from Category L1
        JOIN Category L2
           on L1.Category_ID = L2.Parent
           JOIN Category L3
              on L2.Category_ID = L3.Parent
              LEFT JOIN Category L4
                 on L3.Category_ID = L4.Parent
   where L1.name = "ELECTRONICS"
   group by L3.Category_ID
UNION
select L4.Category_ID,
       L4.name, 
       "4" as HierarchyLevel,
       1 as NextLevelCount
   from Category L1
        JOIN Category L2
           on L1.Category_ID = L2.Parent
           JOIN Category L3
              on L2.Category_ID = L3.Parent
              JOIN Category L4
                 on L3.Category_ID = L4.Parent
   where L1.name = "ELECTRONICS"

这显然固定为 4 个级别,但会将它们合并到一个列表中,但没有您提供的重复项。我还添加了层次结构级别,仅供参考。为了获得每个级别的计数,您必须执行 LEFT JOIN 到下一个级别,否则,您将错过您尝试检索的级别的可能项目,但其他项目应保留为 INNER JOIN。

如果您正在处理产品,我认为如果不是经过 4 层深他们就找不到东西,那就是一个更大的问题 :)

于 2012-05-08T12:54:27.390 回答
1

作为一个兴趣点,因为它可能工作量太大并且与您必须成为“答案”的不同,我建议您研究“修改的预排序树遍历”的概念。Gijs Van Tulder有一个很好的解释

它将需要表上的附加字段来存储层次结构数据,并需要额外的代码来维护该结构,但它可以使树结构容易在关系数据库引擎中处理。

基本上,除了parent_id我们用树存储的通常情况外,我们还存储 aleft和 aright值。node.left > parent.left正确填充后,只需选择所有节点 where和,就可以轻松获得“节点的所有子节点” node.right < parent.right,而不管节点的深度如何。

于 2012-05-08T13:12:52.970 回答
0

你可以这样做:

SELECT name FROM category WHERE name = 'ELECTRONICS'

UNION

SELECT t2.name FROM t2 INNER JOIN category as t1 ON t2.parent = t1.category_id WHERE t1.name = 'ELECTRONICS'

UNION

SELECT t3.name FROM t3 INNER JOIN category as t1 ON t3.parent = t1.category_id WHERE t1.name = 'ELECTRONICS'

UNION

SELECT t4.name FROM t4 INNER JOIN category as t1 ON t4.parent = t1.category_id WHERE t1.name = 'ELECTRONICS'
于 2012-05-08T08:15:13.890 回答