none
ayudenme por favor !! con la herencia de mis lista RRS feed

  • Pregunta

  • si yo tengo en una sola tabla re_listas todos los campos de mi combobox

    yo realizo un procedimiento que me traiga al item padre que es el 117 

    IF @FILTRO = 600 --LISTAS DE tipo de reclamo form reclamo
    BEGIN
    SELECT 
    Id,
    IdPadre,
    Descripcion,
    DescripcionPadre,
    Estado
    FROM RE_LISTA
    WHERE Estado = 1 and IdPadre in (52,117) AND Id NOT IN (118,119,120)
    END

    ---------------------------------------------------------------------------------------------------------------------------------------------------------

    Id IdPadre Descripcion DescripcionPadre Estado

    52 52 -- NO ESPECIFICA -- NULL 1
    117 117 OPORTUNIDAD NULL 1
    134 117 ACCESIBILIDAD NULL 1
    194 117 EFICIENCIA Y PROTECCION FINANCIERA NULL 1
    800 117 OTROS NO CLASIFICADOS EN NINGUN TIPO NULL 1

    -------------------------------------------------------------------------------------------------------------------

    pero cada item a la vez tiene un hijo para que jale al siguiente combobox , mi pregunta es 

    como hago un nuevo IF para que me traiga a la sigruiente lista ??? alguien me dijo que haga un inner join a la misma tabla para que me traiga a los hijos dependiendo al padre seleccionado pero no se como hacerlo 

    ayudenme pliss !!!!!!!!!!!

    sábado, 4 de mayo de 2019 17:09

Respuestas

  • Hola ghiadafne001:

    Es un pelín más complicado que hacer una inner join.

    Te expongo primero tus problemas, con tus datos, y como se resuelven de un modo simple y la solución.

    CREATE TABLE RE_LISTA
    (Id          INT
    , IdPadre     INT
    , Descripcion VARCHAR(100)
    , Estado      TINYINT
    );
    GO
    
    INSERT INTO RE_LISTA
    (Id, IdPadre, Descripcion, Estado)
    VALUES
    (52, NULL, NULL, NULL),
    (117, NULL, 'OPORTUNIDAD', NULL),
    (134, 117, 'ACCESIBILIDAD', NULL),
    (194, 117, 'EFICIENCIA', NULL),
    (800, 117, 'OTROS', NULL),
    (118, NULL, 'NODO A', NULL),
    (119, NULL, 'NODO B', NULL),
    (120, 118, 'NODO C', NULL);
    GO

    Este es el escenario que debe de ser, porque, un nodo hijo no puede ser a la vez padre. Ojo la consulta de salida, puede repetir dos veces el id del hijo, para que no cambies nada, pero no tiene sentido en datos, y hace que las cosas no funcionen bien. Del mismo modo, que no esta normalizado tener datos repetidos, y si un elemento tiene descripción, no tiene porque volver a tenerla quien herede de el.

    Con esta estructura, que es simple, un nodo por ejemplo el 117, 118, 119 y 52 no heredan de nadie. Por tanto su padre es null.

    Primera aproximación.

    WITH cte
    	AS (SELECT Id
    		    , IdPadre
    		    , Descripcion
    		    , Estado
    	    FROM     
    		    RE_LISTA
    	    WHERE    IdPadre IS NULL
    /*Nota 1*/
    	    UNION ALL
    	    SELECT R2.Id
    		    , R2.IdPadre
    		    , R2.Descripcion
    		    , R2.Estado
    	    FROM   
    		    RE_LISTA AS R2
    			    INNER JOIN cte ON cte.ID = R2.IdPadre
    /*Nota 2*/
    )
    	SELECT *
    	FROM   
    		cte;
    


    Nota1

    Esto que te planteo es una consulta recursiva, en la parte de arriba están el/los nodos que hacen la recursividad y en la parte de abajo quien depende de ellos.

    Por tanto la parte superior me trae, 52, 117, 118, 119 que son los nodos de padre null.

    Nota2

    En la parte del UNION ALL

    El solo se trae los mismos datos de todos los nodos cuyo (fíjate bien en la inner join que se relaciona la tabla, contra la parte de arriba) padre sea el id de la parte superior. (máximo hasta 32765 niveles)

    La salida de la query la realiza el Select * from cte

    ---- ---- --------------- ----
    52    NULL NULL                   NULL
    117  NULL OPORTUNIDAD     NULL
    118  NULL NODO A               NULL
    119  NULL NODO B               NULL
    120  118  NODO C                NULL
    134  117  ACCESIBILIDAD     NULL
    194  117  EFICIENCIA           NULL
    800  117  OTROS                  NULL
    (8 filas afectadas)

    Una vez entendido esto, vamos a acercarnos a tu escenario 

    DECLARE @FILTRO INT;
    SET @FILTRO= 117;
    ;WITH cte
    	AS (SELECT Id
    		    , IdPadre
    		    , Descripcion
    		    , Estado
    	    FROM     
    		    RE_LISTA
    	    WHERE   Id = @FILTRO
    	    UNION ALL
    	    SELECT R2.Id
    		    , R2.IdPadre
    		    , R2.Descripcion
    		    , R2.Estado
    	    FROM   
    		    RE_LISTA AS R2
    			    INNER JOIN cte ON cte.ID = R2.IdPadre)
    	SELECT CAST(id as varchar(3)),
    		  CAST(idPadre as varchar(4)),
    		  CAST (descripcion as varchar(15)),
    		  CAST (Estado as varchar(4))
    	FROM   
    		cte;

    Como puedes observar, le he añadido el filtro a la parte superior, y en la salida, puedes obviar los cast, porque los he colocado para poder mostrar la salida formateada como texto y pegarla aquí sin utilizar una imagen.

    ---- ---- --------------- ----
    117  NULL OPORTUNIDAD     NULL
    134  117   ACCESIBILIDAD   NULL
    194  117   EFICIENCIA         NULL
    800  117   OTROS                NULL
    (4 filas afectadas)

    Ahora bien, en tu salida pareces querer la descripción del padre, pero no pareces ponerla. Si la quieres mostrar, entonces tienes que volver a relacionar el cte con la tabla. para obtener la descripción del padre.

    DECLARE @FILTRO INT;
    SET @FILTRO= 117;
    ;WITH cte
    	AS (SELECT Id
    		    , IdPadre
    		    , Descripcion
    		    , Estado
    	    FROM     
    		    RE_LISTA
    	    WHERE   Id = @FILTRO
    	    UNION ALL
    	    SELECT R2.Id
    		    , R2.IdPadre
    		    , R2.Descripcion
    		    , R2.Estado
    	    FROM   
    		    RE_LISTA AS R2
    			    INNER JOIN cte ON cte.ID = R2.IdPadre)
    	SELECT CAST(c.id as varchar(3)),
    		  CAST(c.idPadre as varchar(4)),
    		  CAST(c.descripcion as varchar(15)),
    		  CAST(r.Descripcion as varchar(15)),
    		  CAST(c.Estado as varchar(4))
    	FROM   
    		cte c left join RE_LISTA r on c.IdPadre = r.Id;

    ---- ---- --------------- --------------- ----
    117  NULL OPORTUNIDAD     NULL                   NULL
    134  117  ACCESIBILIDAD    OPORTUNIDAD     NULL
    194  117  EFICIENCIA          OPORTUNIDAD     NULL
    800  117  OTROS                 OPORTUNIDAD     NULL
    (4 filas afectadas)

    Por útilmo si quieres mostrar el null de la columna padre como estaba 117.

    cambias el select cte

    DECLARE @FILTRO INT;
    SET @FILTRO= 117;
    ;WITH cte
    	AS (SELECT Id
    		    , IdPadre
    		    , Descripcion
    		    , Estado
    	    FROM     
    		    RE_LISTA
    	    WHERE   Id = @FILTRO
    	    UNION ALL
    	    SELECT R2.Id
    		    , R2.IdPadre
    		    , R2.Descripcion
    		    , R2.Estado
    	    FROM   
    		    RE_LISTA AS R2
    			    INNER JOIN cte ON cte.ID = R2.IdPadre)
    	SELECT CAST(c.id as varchar(3)),
    		  CAST((case when c.idPadre Is null then c.Id else c.IdPadre end) as varchar(4)),
    		  CAST(c.descripcion as varchar(15)),
    		  CAST(r.Descripcion as varchar(15)),
    		  CAST(c.Estado as varchar(4))
    	FROM   
    		cte c left join RE_LISTA r on c.IdPadre = r.Id;

                                             
    ---- ---- --------------- --------------- ----
    117  117  OPORTUNIDAD     NULL                  NULL
    134  117  ACCESIBILIDAD   OPORTUNIDAD     NULL
    194  117  EFICIENCIA         OPORTUNIDAD     NULL
    800  117  OTROS                OPORTUNIDAD     NULL
    (4 filas afectadas)

    Puedes echarle un ojo a estos artículos sobre esta recursividad que te pueden ayudar bastante.

    Recursividad

    https://javifer2.blogspot.com/search/label/tablas%20de%20expresi%C3%B3n%20com%C3%BAn%20%283%29%20recursividad

    Avanzado

    https://javifer2.blogspot.com/search/label/tablas%20de%20expresi%C3%B3n%20com%C3%BAn%20%283%29%20recursividad%20avanzado

    domingo, 5 de mayo de 2019 6:15