首页 > 解决方案 > Mysql如何获取给定ID的父母和所有孩子?

问题描述

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

类别表:

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

产品表:

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使用此查询连接表:

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)

更新: 数据库模型

在此处输入图像描述

有人可以帮帮我吗?谢谢你。

标签: mysqlsqlselecthierarchyhierarchical-data

解决方案


首先应该注意的是,您的查询不会给您根类别,只有它的子类别。因此,您需要向UNION其中添加一个以包含根类别。其次,递归部分不需要子查询,可以直接在查询中进行排序。然后,您可以将该查询用作派生表并将JOIN其用于该products表:

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

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

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

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

dbfiddle 上的演示


推荐阅读