在MySQL中不允许在递归公用表表达式中使用LIMIT

问题描述 投票:1回答:1

我的目标是使用最新的MySQL的WITH RECURSIVE方法构造树。

我的表称为categories,它有2行。 IDparentID row

我的类别表:

 . ID . | ParentID   
--------|----------
 . 1  . | null  
 . 2  . |  1
 . 3  . |  1  
 . 4  . |  1
 . 6  . |  1
 . 7  . |  1
 . 8  . |  1
 . 9  . |  1
 . 10 . |  1
 . 11 . |  13
 . 12 . |  14
 . 13 . |  12     
 .... . | ...

ID从2到9,具有相同的父代,而父代ID为1。这是我试图通过在递归公用表表达式的第二个SELECT查询中提供“ LIMIT 5”来限制的目的。

树中上表的光学表示将类似于以下内容:我的问题是限制相同级别的孩子数量(在下图中标记为项目Y)。

+ Item X .............. (level 1)       
  + Item Y .............. (level 2)  
  + Item Y .............. (level 2)   
  + Item Y .............. (level 2) 
  + .... LIMIT to 5 Items 
+ Item X
    + Item X
      + Item X
         + Item X
             + Item X  
+ Item X

这是导致问题的LIMIT子句的mySQL Recursive Common Table Expression查询:

WITH RECURSIVE cte AS
(
  SELECT ID, 0 AS depth, CAST(ID AS CHAR(200)) AS path
    FROM categories WHERE parentID = 1
  UNION ALL
  SELECT c.ID, cte.depth+1, CONCAT(cte.path, ',', c.ID)
    FROM categories c 
    JOIN cte ON cte.ID = c.parentID
    WHERE FIND_IN_SET(c.ID, cte.path)=0 AND depth <= 10
    LIMIT 5
)

逻辑上,我期望通过在CTE的第二个Select部分中使用LIMIT子句来限制我的问题,以限制第二个SELECT语句返回的行数。但这给了我一个错误:

This version of MySQL doesn't yet support 'ORDER BY / LIMIT over UNION in recursive Common Table Expression'

注意,我正在使用MySQL 8.0 +版本。我知道错误很明显。但是,如果我有100万个孩子在同一个父母以下,该怎么办?它将冻结系统!

我将非常感谢一种解决方法。

谢谢。

php mysql sql mysqli
1个回答
0
投票

如果我正确地跟随了您,row_number()可以做您想要的。这个想法是枚举对应部分的categories行,然后在前5个位置进行过滤:

with recursive cte as (
    select id, 0 as depth, cast(id as char(200)) as path
    from categories 
    where parentid = 1
    union all
    select c.id, cte.depth+1, concat(cte.path, ',', c.id)
    from cte
    inner join (
        select c.*, row_number() over(partition by c.parentid order by c.id) rn
        from categories c 
    ) c on cte.id = c.parentid
    where find_in_set(c.id, cte.path) = 0 and depth <= 10 and c.rn <= 5
)
select * from cte
© www.soinside.com 2019 - 2024. All rights reserved.