none
Cómo hago una consulta SQL jerárquica para un presentar un foro RRS feed

  • Pregunta

  • Hola,

    Quiero hacer una consulta SQL para mostrar los mensajes de un foro, pero no logro hacerlo.

    Las columnas son las siguientes:

    Numero = Numero de mensaje

    Respuesta = Respuesta al mensaje o mensaje Padre "Numero"

    Mensaje = Mensaje de texto

    Los datos como quiero que aparezcan:

    Numero, Respuesta, Mensaje:

    1,0,"Mensaje 1"

    2,1,"Respuesta al 1"

    4,2,"Respuesta al 2"

    3,1,"Respuesta al 1"

    con al siguiente consulta:

    Select Numero,Respuesta,Mensaje 
    From Mensaje Where Respuesta = 0
    Union all
    Select x.Numero, x.Respuesta, x.Mensaje
    From Mensaje x Inner Join Mensaje z On x.Respuesta  = z.Numero

    Obtengo esto:

    1,0,"Mensaje 1"

       2,1,"Respuesta al 1"

       3,1,"Respuesta al 1"

          4,2,"Respuesta al 2"

    Pero yo quiero esto:

    1,0,"Mensaje 1"

       2,1,"Respuesta al 1"

          4,2,"Respuesta al 2"

       3,1,"Respuesta al 1"

    Agradecería saber como hacerlo.


    • Editado Fran-k2 viernes, 17 de mayo de 2019 7:56
    miércoles, 15 de mayo de 2019 15:36

Respuestas

Todas las respuestas

  • Hola  

    Gracias por levantar tu consulta en los foros de MSDN. Con respecto a la misma, te hago la recomendación de ingresar al siguiente enlace en donde se expone un caso similar al que presentas y pudieras encontrar una posible solución.

    https://social.msdn.microsoft.com/Forums/es-ES/9b791b25-bbe6-47ef-8f41-5304db79c600/consulta-jerrquica?forum=sqlserveres

    https://social.msdn.microsoft.com/Forums/es-ES/63f939ac-4ff1-439a-a22a-391427ed6d73/consulta-jerarquica-en-datagridview?forum=winformses

    Gracias por usar los foros de MSDN.

    Carlos Ruiz
     ____

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde. 

    Microsoft ofrece este servicio de forma gratuita, con la finalidad de ayudar a los usuarios y la ampliación de la base de datos de conocimientos relacionados con los productos y tecnologías de Microsoft.  

    Este contenido es proporcionado "tal cual" y no implica ninguna responsabilidad de parte de Microsoft.

    miércoles, 15 de mayo de 2019 16:40
  • Hola Fran-k2:

    Puedes utilizar un cte recursivo.


    create table respuestas (numero int, respuesta int ,mensaje varchar(100))
    go
    insert into respuestas (numero, respuesta, mensaje)
    values
    (1,0,'Mensaje1'),
    (2,1,'Respuesta al 1'),
    (4,2,'Respuesta al 2'),
    (3,1,'Respuesta al 1');
    go

    Con tu escenario ya creado, una de las posibles soluciones

    WITH cte
    	AS (SELECT numero
    		    , respuesta
    		    , mensaje
    		    , 0 as level
    		    ,ROW_NUMBER() OVER(PARTITION BY respuesta ORDER BY numero) / POWER(10.0, 0) AS x
    	    FROM     
    		    respuestas
    	    WHERE   respuesta = 0
    	    UNION ALL
    	    SELECT b.numero
    	    ,b.respuesta
    	    ,b.mensaje
    	    , c.level + 1
    	    , x + ROW_NUMBER() 
    		  OVER(PARTITION BY b.respuesta ORDER BY b.numero) / POWER(10.0, level + 1)
    
    	    FROM   
    		    respuestas b
    			    INNER JOIN cte c ON b.respuesta = c.numero)
    	SELECT cte.numero, cte.respuesta, cte.mensaje
    	FROM   
    		cte
    		order by x

    Salida

    Ctes recursivos

    https://javifer2.blogspot.com/2019/01/with-cte-tablas-de-expresion-comun.html

    https://javifer2.blogspot.com/search/label/tablas%20de%20expresión%20común%20%283%29%20recursividad%20avanzado

    • Propuesto como respuesta HunchbackMVP miércoles, 15 de mayo de 2019 18:24
    • Marcado como respuesta Fran-k2 viernes, 17 de mayo de 2019 14:25
    miércoles, 15 de mayo de 2019 17:21
  • Hola Javi Fernandez F.

    Lo primero agradecerte tu respuesta. El caso es que para las primeras respuestas funciona pero he insertado algunas respuestas mas y entonces ya no funciona.

    Esto seria el resultado de tu consulta:

    Pero el resultado correcto seria:

    1,0,"Mensaje 1"

        2,1,"Respuesta al 1"

            4,2,"Respuesta al 2"

                6,4,"Respuesta al 4"

            7,2,"Respuesta al 2"

        3,1,"Respuesta al 1"

        5,2,"Respuesta al 1"

    He estado viendo las consultas de casos similares pero creo que esto es distinto. Creo que esto es bastante mas complicado.

    Un saludo.







    • Editado Fran-k2 viernes, 17 de mayo de 2019 9:57
    viernes, 17 de mayo de 2019 7:39
  • Fran-k2,

    La fila (5, 2, 'Respuesta al 1') debe ser (5, 1, 'Respuesta al 1').

    Aca otra forma de ordenar el resultado.

    DECLARE @respuestas table (
    numero int, 
    respuesta int ,
    mensaje varchar(100)
    );
    
    insert into @respuestas (numero, respuesta, mensaje)
    values
    	(1, 0, 'Mensaje1'),
    	(2, 1, 'Respuesta al 1'),
    	(4, 2, 'Respuesta al 2'),
    	(6, 4, 'Respuesta al 4'),
    	(7, 2, 'Respuesta al 2'),
    	(3, 1, 'Respuesta al 1'),
    	(5, 1, 'Respuesta al 1')
    ;
    
    WITH R AS (
    SELECT
    	numero, 
    	respuesta, 
    	mensaje,
    	0 AS lvl,
    	CAST(numero AS varbinary(900)) AS [path]
    FROM
    	@respuestas
    WHERE
    	respuesta = 0
    
    UNION ALL
    
    SELECT
        C.numero,
        C.respuesta,
        C.mensaje,
    	P.lvl + 1,
    	CAST(P.[path] + CAST(ROW_NUMBER() OVER(PARTITION BY C.respuesta ORDER BY C.numero) AS binary(4)) AS varbinary(900))
    FROM
    	R AS P
    	INNER JOIN
    	@respuestas AS C
    	ON C.respuesta = P.numero
    )
    SELECT
    	CONCAT(REPLICATE('||||', 4 * lvl), numero, ' . ', respuesta, ' - ', R.mensaje) AS col1
    FROM
    	R
    ORDER BY
    	[path]
    GO


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    viernes, 17 de mayo de 2019 12:38
  • Hola Fran-k2:

    Coincido con lo que te ha explicado el moderador de este foro. El ordenamiento parece correcto, y ambas sentencias dan un resultado correcto. Ese registro 5.2 "respuesta al 1" debiera de ser 5.1

    O tú criterio de ordenación es diferente. Pero no lo has presentado adecuadamente, para que quienes lo vemos, lo hayamos entendido.

    Da igual que apliques una consulta o la otra, porque te dan los mismo resultados.

    viernes, 17 de mayo de 2019 13:51
  • Hola Javi Fernández.

    No me había dado cuenta del error que cometí al insertar los registros. Efectivamente el registro 5.2 debería ser 5.1 eso era todo. En realidad funcionaba todo bien desde un principio, el error fue mio. Mil perdones por el error.

    Ya he marcado tu consulta como respuesta y os he votado a los dos.

    Ahora tengo que intentar estudiar tu consulta a ver si consigo entenderla, pero eso ya es cosa mia.

    Mil gracias y mil perdones a los dos.

    Saludos.

    viernes, 17 de mayo de 2019 14:35
  • De nada. 
    viernes, 17 de mayo de 2019 17:06