如何创建一个sql调用,递归地将不同的ID和父ID合并到一个列中?

iyfamqjs  于 2021-06-15  发布在  Mysql
关注(0)|答案(1)|浏览(336)

我有一个 company 引用自身的表,如下所示:

company_id    parent_id
-----------------------
1             (NULL)   
2             1        
3             2             
4             1
5             (NULL)

所以 company 可以有一个父母 company 等等。
我还有一个查找表来连接 customer 与他们相关的 company 例如:

customer_id     company_id
--------------------------
1               1
1               3
1               4
2               3
2               2

我正在尝试创建一个sql调用,该调用将获取与客户id相关的不同公司id的列表。这意味着我不仅需要从查找表中获取一对一关系的公司id,还需要遍历所有父项,如果父项id不在列表中,请添加父项id,然后查看父项的父项,如果他们还没有在列表中,就添加他们的ID,以此类推。
例如,在上面的表格中,如果我试图找到所有的公司id where customer_id = 2 ,我希望能回来:

company_id
---------------
1
2
3

注意,它递归地得到了1,但是它没有列出2两次,因为它只寻找不同的id。
不过,当涉及到递归sql调用时,我相当迷茫。这是可能的还是我应该在代码中这样做?

muk1a3rh

muk1a3rh1#

在mysql 8.0及更高版本中,可以使用递归cte遍历层次结构。但由于你的客户已经有了一些他们指定的公司的母公司(这对我来说有点奇怪),这将导致重复。所以你需要得到不同的集合。为了方便起见,我使用了另一个cte,但你也可以跳过它,做同样的事情 DISTINCT 直接在您的查询中。然后您可以简单地从cte查询客户的公司。

WITH RECURSIVE
cte1 AS
(
SELECT cu.customer_id,
       cu.company_id
       FROM customer cu
UNION ALL
SELECT ct.customer_id,
       co.parent_id company_id
       FROM cte1 ct
            INNER JOIN company co
                       ON ct.company_id = co.company_id
       WHERE co.parent_id IS NOT NULL
),
cte2 AS
(
SELECT DISTINCT
       ct.customer_id,
       ct.company_id
       FROM cte1 ct
)
SELECT company_id
       FROM cte2
       WHERE customer_id = 2;

小提琴
当然,您也可以将customer id上的条件转移到递归cte的锚点中。如果您只需要为一个客户进行查询,那么这可能会降低查询的成本。

相关问题