2010-12-06 9 views
5

que tienen una base de datos que, esencialmente, se ve así:¿Ordenar una estructura de lista enlazada en una consulta SQL o LINQ?

id uniqueidentifier NOT NULL 
data nvarchar 
nextid uniqueidentifier NULL 

Esta es una lista enlazada, ya que cada NextID enlaces a un id de esa tabla, a excepción de la última, aquí NextID es NULL. Sé la identificación del primer nodo.

Quiero SELECCIONARlas todas en el orden correcto, con una identificación de inicio.

¿Hay alguna manera de hacerlo en T-SQL (Edición: SQL 2008) o LINQ?

Sé que puedo escribir código para hacerlo manualmente en C#, ¿me pregunto si ya puedo consultar en ese orden?

Respuesta

5

No estoy seguro de que [SortOrder] haga la diferencia, ya que no tengo suficientes datos para probarlo. Le permite ordenar en ambas direcciones.

with cteList as 
(
    select id, data, nextid, 1 as [SortOrder] 
    from #TableTemp 
    where id = 'E8ADAA52-54F8-4FE3-BE59-9852E52B33F5' --id of the 1st item 

    union all 

    select #TableTemp.id, #TableTemp.data, #TableTemp.nextid, (cteList.[SortOrder] + 1) as [SortOrder] 
    from #TableTemp 
    join cteList on #TableTemp.id = cteList.nextid 
) 
select * from cteList 
order by [SortOrder] asc 
+0

¡Esto es genial! '(cteList. [SortOrder] + 1)' debería ser simplemente '([SortOrder] + 1)', de lo contrario, SQL se queja de que el identificador de varias partes no pudo ser enlazado –

+0

¡Gracias por el comentario! Por alguna razón, me funcionó en mssql 2005 enterprise manager cuando escribí la consulta. –

3

¿Qué versión de SQL Server? Si es 2005 o más reciente, puede usar un CTE recursivo.

with linked_list as (
    select 
    id, data, nextid 
    from 
    table 
    where 
    id = @head 
    union all 
    select 
    t.id, t.data, t.nextid 
    from 
    table t 
    join linked_list ll on t.id = ll.nextid 
) 
select 
    * 
from 
    linked_list 
+0

Buen trabajo con el CTE. Probablemente sería bueno editar para aplicar el orden correcto de las filas de resultados ya que 'UNION [ALL]' no garantiza un orden en particular. –

+0

Interesante, eso funciona. Lo he cambiado para iterar hacia atrás (donde ID es NULO, únete a ll.id = t.nextid), ¿hay alguna forma de revertir el conjunto de resultados? (solo curiosidad, también puedo hacerlo en LINQ) –

+0

@Phil: solo me preguntaba si el Join garantizaría el pedido. En mi prueba funciona bien, pero hasta ahora solo tengo un pequeño conjunto de pruebas. –

Cuestiones relacionadas