此查询:
SELECT pcn.id,
pcn.config_id,
pcnc.nombre_nivel,
pcnc.orden_nivel,
pcn.nivel_padre_id,
pcnc.empresa_id,
pcnc.proyecto_id,
pcnc.activo AS activo_config,
pcnc.usuario_id,
pcn.activo
FROM puebles_ciclos_niveles pcn
JOIN puebles_ciclos_niveles_config pcnc ON pcn.config_id = pcnc.id
提供以下结果:
我需要的数据顺序如下:
这里的“nivel_padre_id”代表父ID。
我尝试过用 CTE 表来制作它,问题是 CTE 表只处理一个级别,如下所示:
WITH RecursiveCTE AS (
SELECT
pcn.id, pcn.config_id, pcnc.nombre_nivel, pcnc.orden_nivel,pcn.nivel_padre_id,
pcnc.empresa_id, pcnc.proyecto_id, pcnc.activo AS activo_config, pcnc.usuario_id,pcn.activo
FROM
puebles_ciclos_niveles pcn
JOIN
puebles_ciclos_niveles_config pcnc ON pcn.config_id = pcnc.id
WHERE
pcn.nivel_padre_id = 0 -- Selecting the root level
UNION ALL
SELECT
pcn.id, pcn.config_id, pcnc.nombre_nivel, pcnc.orden_nivel, pcn.nivel_padre_id, pcnc.empresa_id, pcnc.proyecto_id,
pcnc.activo AS activo_config, pcnc.usuario_id, pcn.activo
FROM
puebles_ciclos_niveles pcn
JOIN
puebles_ciclos_niveles_config pcnc ON pcn.config_id = pcnc.id
JOIN
RecursiveCTE rc ON pcn.nivel_padre_id = rc.id
)
SELECT
id, config_id, nombre_nivel, orden_nivel,
nivel_padre_id, empresa_id, proyecto_id,
activo_config, usuario_id, activo
FROM
RecursiveCTE
此 CTE 查询生成以下内容:
有什么办法可以得到想要的结果吗? (Parent - Child(1) - Child(2) - Child(3) - Children (4) -如果没有找到更多的children则停止,返回处理上一级-)
因为您希望结果集中有特定的排序,所以需要提供
order by
子句。但是用什么来订购呢?这是您的查询,添加了一列 - path
,它表示从根节点到该特定行的路径。
WITH RecursiveCTE AS (
SELECT
pcn.id, pcn.config_id, pcnc.nombre_nivel, pcnc.orden_nivel,pcn.nivel_padre_id,
pcnc.empresa_id, pcnc.proyecto_id, pcnc.activo AS activo_config, pcnc.usuario_id,pcn.activo,
[path] = cast(concat('/', pcn.id, '/' ) as varchar(1000))
FROM
puebles_ciclos_niveles pcn
JOIN
puebles_ciclos_niveles_config pcnc ON pcn.config_id = pcnc.id
WHERE
pcn.nivel_padre_id = 0 -- Selecting the root level
UNION ALL
SELECT
pcn.id, pcn.config_id, pcnc.nombre_nivel, pcnc.orden_nivel, pcn.nivel_padre_id, pcnc.empresa_id, pcnc.proyecto_id,
pcnc.activo AS activo_config, pcnc.usuario_id, pcn.activo,
[path] = cast(concat(rc.[path], pcn.id, '/' ) as varchar(1000))
FROM
puebles_ciclos_niveles pcn
JOIN
puebles_ciclos_niveles_config pcnc ON pcn.config_id = pcnc.id
JOIN
RecursiveCTE rc ON pcn.nivel_padre_id = rc.id
)
SELECT
id, config_id, nombre_nivel, orden_nivel,
nivel_padre_id, empresa_id, proyecto_id,
activo_config, usuario_id, activo,
[path]
FROM
RecursiveCTE
order by [path];
通过说明,基本元素的
path
就是该行的 id
,由斜线包围。对于后续/递归元素,我采用父级的路径,将此行的 id
附加到它,并以另一个斜杠结束。这是一个带有演示的db fiddle。
注意 - 路径格式的选择不是任意的。 SQL Server 有一种名为 hierarchyid 的数据类型,您可以使用它来获得这种行为,其成本比在查询时动态计算它要便宜得多(需要在数据突变时维护它的开销)。如果您选择使用我使用的
path
格式,则可以直接转换为 hierarchyid
。