MySQL递归查询cte

时间:2021-05-19 07:49:51

标签: mysql common-table-expression

以下查询

WITH RECURSIVE cte AS
(
  SELECT id, CAST(name AS CHAR(200)) AS name, parentid, icon, url, position,
         CAST(id AS CHAR(200)) AS path,
         0 as depth
  FROM categories WHERE parentid = 46
  UNION ALL
  SELECT c.id,
         c.name,
         c.parentid,
         c.icon,
         c.url,
         c.position,
         CONCAT(cte.path,',', c.id),
         cte.depth+1
  FROM categories c JOIN cte ON
  cte.id=c.parentid
)
SELECT id, path FROM cte ORDER BY id;

这将返回两列:IDPath。如果 ID 是例如“52”,路径是“50,51,52”,其中 50 和 51 是父母和祖父母,52 是 ID 本身。如何在没有“52”ID 的情况下获得“50,51”的结果?谢谢!

<table>
<thead>
<tr>
<th>ID </th>
<th>Parentid</th>
</tr>
</thead>
<tbody>
<tr><td>    46  </td><td>   0   </td></tr>
<tr><td>    47  </td><td>   46  </td></tr>
<tr><td>    48  </td><td>   46  </td></tr>
<tr><td>    49  </td><td>   46  </td></tr>
<tr><td>    50  </td><td>   46  </td></tr>
<tr><td>    51  </td><td>   50  </td></tr>
<tr><td>    52  </td><td>   51  </td></tr>
<tr><td>    53  </td><td>   47  </td></tr>
<tr><td>    54  </td><td>   47  </td></tr>
<tr><td>    55  </td><td>   47  </td></tr>
<tr><td>    56  </td><td>   48  </td></tr>
<tr><td>    57  </td><td>   51  </td></tr>
<tr><td>    58  </td><td>   49  </td></tr>
<tr><td>    60  </td><td>   50  </td></tr>
</tbody>
</table>

1 个答案:

答案 0 :(得分:0)

在构建 path 字段值期间,您似乎试图排除那些不是父级的 ID。

您可以使用 select 子句获得条件 WHEN

WITH RECURSIVE cte AS
(
  SELECT id, CAST(name AS CHAR(200)) AS name, parentid, icon, url, position,
         CAST(id AS CHAR(200)) AS path,
         0 as depth
  FROM categories WHERE parentid = 46
  UNION ALL
  SELECT c.id,
         c.name,
         c.parentid,
         c.icon,
         c.url,
         c.position,
         CASE WHEN  c.id not in (select parentid from categories) THEN CONCAT(cte.path)
              ELSE  CONCAT(cte.path,',', c.id) END as path
         ,cte.depth+1
  FROM categories c 
  JOIN cte ON cte.id=c.parentid
)
SELECT id, path FROM cte ORDER BY id;

试试这个dbfiddle