Mysql 如何获取给定 ID 的父项和所有子项?

Mysql how to get parent and all child for given ID?

我有两个 table(类别,产品)如下:

类别Table:

cid name parent
1  items Null
2    A    1
3    aa   2
4    ab   2
5    ac   2
6    B    1
7    ba   5
8    bb   5
9    bc   5
10   C    1
11   ca   9
12   cb   9
13   cc   9

产品Table:

pid  cid  pname
1     2   p1
2     3   p2
3     4   p3
4     4   p4
5     5   p5
6     5   p6

这里我想获取特定父项的所有父项和子项产品。这里我有 cid = 2,然后我需要 cid=2 及其子项的所有产品。

我在这里尝试过类似的操作,但不确定如何使用此查询加入 product table:

select  cid,
        name,
        parent
from    (select * from categories
         order by parent, cid) categories,
        (select @pv := '2') initialisation
where   find_in_set(parent, @pv) > 0
and     @pv := concat(@pv, ',', cid)

更新: 数据库模型

有人能帮帮我吗? 谢谢你。

select product.pname, product.cid, category.parent
  from product 
 inner join category
    on product.cid = catgeory.cid; 

首先应该注意的是,您的查询不会为您提供根类别,而只会提供其子类别。所以你需要给它添加一个 UNION 来包含根类别。其次你不需要递归部分的子查询,你可以直接在查询中进行排序。然后,您可以将该查询用作 table 和 JOIN 的派生查询 products table:

SELECT *
FROM (
      SELECT 2 AS cid
      UNION ALL
      (SELECT  cid
       FROM categories
       CROSS JOIN (SELECT @pv := '2') initialisation
       WHERE   find_in_set(parent, @pv) > 0
         AND   @pv := concat(@pv, ',', cid)
       ORDER BY parent, cid)
      ) c
JOIN products p ON p.cid = c.cid

输出(对于您的示例数据)

cid     pid     cid     pname
2       1       2       p1
3       2       3       p2
4       3       4       p3
4       4       4       p4
5       5       5       p5
5       6       5       p6

您可能只需要一个产品名称列表,在这种情况下,您可以将外部查询中的 * 替换为例如GROUP_CONCAT(p.pname) AS products 得到结果:

products
p1,p2,p3,p4,p5,p6

Demo on dbfiddle

要同时获取类别名称,您必须SELECT在内部查询中:

SELECT *
FROM (
      SELECT cid, name
      FROM categories
      WHERE cid = 2
      UNION ALL
      (SELECT  cid, name
       FROM categories
       CROSS JOIN (SELECT @pv := '2') initialisation
       WHERE   find_in_set(parent, @pv) > 0
         AND   @pv := concat(@pv, ',', cid)
       ORDER BY parent, cid)
      ) c
JOIN products p ON p.cid = c.cid

输出:

cid     name    pid     cid     pname
2       A       1       2       p1
3       aa      2       3       p2
4       ab      3       4       p3
4       ab      4       4       p4
5       ac      5       5       p5
5       ac      6       5       p6

Demo on dbfiddle