选择查询中的更改

时间:2012-05-08 08:03:06

标签: php mysql

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

enter image description here

通过此查询

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';

得到那样的结果

enter image description here

但我希望得到这样的结果,有任何选择吗

enter image description here

提前致谢

4 个答案:

答案 0 :(得分:1)

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

此问题的一个出色解决方案是为菜单you can read more here使用nested set结构。有关如何使用mysql here执行此操作的更多说明。

答案 1 :(得分: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级深度后他们找不到东西,就会出现更大的问题:)

答案 2 :(得分:1)

作为一个兴趣点,因为它可能是太多的工作而且与你必须作为“答案”不同,我建议你研究“修改预先排序的树遍历”的概念。有一个很棒的explanation by Gijs Van Tulder

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

基本上,除了我们存储树的常用parent_id之外,我们还存储了leftright值。正确填充后,只需选择node.left > parent.leftnode.right < parent.right的所有节点,无论节点的深度如何,都可以轻松获得“节点的所有子节点”。

答案 3 :(得分: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'