2009-02-19 15 views
9

Imagen que está creando un esquema de base de datos para un tablero de discusión enhebrado. ¿Hay una manera eficiente de seleccionar una lista ordenada correctamente para un hilo dado? El código que he escrito funciona pero no se ordena de la manera que me gustaría.SQL CTE recurrentes y ordenación de clasificación personalizada

Digamos que usted tiene estos datos:

ID | ParentID 
----------------- 
1 | null 
2 | 1 
3 | 2 
4 | 1 
5 | 3

Así que la estructura se supone que debe tener este aspecto:

1 
|- 2 
| |- 3 
| | |- 5 
|- 4

Lo ideal sería que en el código, queremos que el conjunto de resultados a aparecer en el siguiente orden: 1, 2, 3, 5, 4
PROBLEMA: Con el CTE escribí que en realidad está siendo devuelto como: 1, 2, 4, 3, 5

Sé que esto sería fácil de agrupar/ordenar mediante el uso de LINQ, pero soy reacio a hacer esto en la memoria. Parece que la mejor solución en este punto, sin embargo ...

Aquí está el CTE actualmente estoy usando:

with Replies as ( 
    select c.CommentID, c.ParentCommentID 1 as Level 
     from Comment c 
     where ParentCommentID is null and CommentID = @ParentCommentID 

    union all 

    select c.CommentID, c.ParentCommentID, r.Level + 1 as Level 
     from Comment c 
     inner join Replies r on c.ParentCommentID = r.CommentID 
) 

select * from Replies 

Cualquier ayuda se agradece; ¡Gracias!



Soy nuevo en SQL y no había oído hablar antes del tipo de datos hierarchyid. Después de leer al respecto desde this comment, decidí que podría querer incorporar esto en mi diseño. Voy a experimentar con esto esta noche y publicar más información si tengo éxito.


actualización
resultado devuelto de mis datos de la muestra, utilizando la sugerencia de dance2die:

ID | ParentID | Level | DenseRank 
------------------------------------- 
15  NULL   1   1 
20  15   2   1 
21  20   3   1 
17  22   3   1 
22  15   2   2 
31  15   2   3 
32  15   2   4 
33  15   2   5 
34  15   2   6 
35  15   2   7 
36  15   2   8
+0

los dioses sql crecen indignados de sus reclamos – Shawn

Respuesta

0

Hmmmm - No estoy seguro de si su estructura es la más adecuada para este problema. De todos modos, no puedo pensar en ordenar los datos como lo quieres dentro de la consulta anterior.

Lo mejor que puedo pensar es si tiene una tabla principal que vincule sus comentarios (por ejemplo, una tabla de temas). Si lo hace, debería poder simplemente unir sus respuestas a eso (tendrá que incluir la columna correcta, obviamente), y luego puede ordenar por el topicID, Level para obtener el orden de clasificación que busca (o cualquier otra información sobre la tabla de tema representa un buen valor para la clasificación).

0

Considere almacenar toda la jerarquía (con activadores para actualizarla si cambia) en un campo.

este campo en su ejemplo podría tener: 1,2 1.2.3 1.2.5 1,4

a continuación, sólo tiene que ordenar en ese campo, probar esto y ver:

create table #temp (test varchar (10)) 
insert into #temp (test) 
select '1' 
union select '1.2' 
union select '1.2.3' 
union select '1.2.5' 
union select '1.4' 
select * from #temp order by test asc 
+0

sí - esto se llama ruta materializada –

8

Estoy seguro de que va a amor esto. recientemente me entero de Dense_Rank() función, que es para "ranking dentro de la partición de un conjunto de resultados", según MSDN

Salida el código abajo y cómo "CommentID" está ordenada.

Por lo que tengo entendido, está intentando dividir su conjunto de resultados mediante ParentCommentID.

Preste atención a la columna "denserank".

with Replies (CommentID, ParentCommentID, Level) as 
(
     select c.CommentID, c.ParentCommentID, 1 as Level 
     from Comment c 
     where ParentCommentID is null and CommentID = 1 

     union all 

     select c.CommentID, c.ParentCommentID, r.Level + 1 as Level 
     from Comment c 
       inner join Replies r on c.ParentCommentID = r.CommentID 
) 
select *, 
     denserank = dense_rank() over (partition by ParentCommentID order by CommentID) 
from Replies 
order by denserank 

alt text

Resultado continuación

+0

Gracias por la sugerencia, estaba tratando de conseguir dense_rank() para trabajar al principio sin suerte. Solicité tu código en mis datos de muestra y funcionó ... casi. Una fila estaba fuera de servicio. Publicaré los datos arriba. –

1

Usted tiene que usar hierarchyid (sólo SQL2008) o un montón de cuerdas (byte o) concatenación.

Cuestiones relacionadas