es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Declaración de recursión CTE con autojoin sin IDs.

Tengo que dividir la columna de datos y establecer una relación con el empleado y el gerente.

Tabla DetallesDelGerente:

datos empleado gerente
imp/imp2/imp3/imp4 imp2 noimp4
noimp1/noimp2/noimp3/noimp4 imp3 imp4

Si observas la tabla de salida a continuación, si tomo la primera fila, el imp4 es el gerente de imp3, imp3 es el gerente de imp2, imp2 es el gerente de imp, por lo que necesito construir la tabla como se menciona a continuación.

Resultado esperado para la primera fila:

datos empleado gerente
imp/imp2/imp3/imp4 imp4
imp/imp2/imp3 imp4 imp3
imp/imp2 imp3 imp2
imp imp2 imp

Utilicé CTE para dividir las filas de DetallesDelGerente con referencia a Link y realicé la consulta:

DECLARE @separator varchar(1) = '/';
WITH rCTE AS(
    SELECT
       1 as [nivel] ,
       d.datos,
       CHARINDEX(@separator, CONCAT(d.datos, @separator)) AS Posicion
    FROM DetallesDelGerente d   
    UNION ALL
    SELECT
       r.[nivel] + 1,
       r.datos,
       CHARINDEX(@separator, CONCAT(r.datos, @separator), r.Posicion + 1) AS Posicion
    FROM rCTE r
    WHERE CHARINDEX(@separator, CONCAT(r.datos, @separator), r.Posicion + 1) > 0
)
SELECT [nivel], SUBSTRING(CONCAT(datos, @separator), 1, Posicion - 1) AS [Valor]
FROM rCTE
ORDER BY [nivel], Posicion DESC
OPTION (MAXRECURSION 0)

Con la consulta anterior puedo mostrar la columna de datos como se espera, pero no puedo cambiar las columnas de gerente y empleado como se esperaba.

Agradezco cualquier tipo de ayuda.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para dividir la columna data y construir la relación con las columnas employee y manager, puede utilizar la CTE previamente creada como una subconsulta y unirla con la tabla ManagerDetails varias veces según el nivel de la cadena dividida.

    Considere la siguiente consulta:

    DECLARE @separator varchar(1) = '/';
    WITH rCTE AS (
        SELECT
            1 AS [level],
            d.data,
            CHARINDEX(@separator, CONCAT(d.data, @separator)) AS Position
        FROM ManagerDetails d
        UNION ALL
        SELECT
            r.[level] + 1,
            r.data,
            CHARINDEX(@separator, CONCAT(r.data, @separator), r.Position + 1) AS Position
        FROM rCTE r
        WHERE CHARINDEX(@separator, CONCAT(r.data, @separator), r.Position + 1) > 0
    )
    SELECT 
        r.[level], 
        SUBSTRING(CONCAT(data, @separator), 1, Position - 1) AS [Value], 
        emp.employee, 
        mgr.manager
    FROM rCTE r
    LEFT JOIN ManagerDetails emp ON r.[level] + 1 = CHARINDEX(@separator, CONCAT(emp.data, @separator), r.Position + 1) / 2
    LEFT JOIN ManagerDetails mgr ON r.[level] = CHARINDEX(@separator, CONCAT(mgr.data, @separator), r.Position) / 2
    ORDER BY r.[level], r.Position DESC;
    

    Aquí, la CTE se utiliza para dividir la columna data y proporcionar el nivel de cada valor dividido. Luego, la subconsulta se une varias veces con la tabla ManagerDetails para recuperar los valores employee y manager para cada nivel dividido. Tenga en cuenta que la segunda condición de unión utiliza la función CHARINDEX para determinar la posición del valor dividido en la columna data original, y luego se divide por 2 para obtener el nivel del valor dividido.

    La salida resultante tendrá cuatro columnas: level, Value (el valor dividido de la columna data), employee (el nombre de empleado correspondiente para ese nivel dividido) y manager (el nombre de gerente correspondiente para ese nivel dividido). Luego puede utilizar esta salida para construir la tabla deseada como se muestra en la pregunta.

Comments are closed.