2010-12-06 9 views
5

J'ai une base de données qui ressemble essentiellement comme ceci:Commande d'une structure de liste liée dans une requête SQL ou LINQ?

id uniqueidentifier NOT NULL 
data nvarchar 
nextid uniqueidentifier NULL 

Ceci est une liste chaînée, comme chacun des liens NextID à un id dans ce tableau, à l'exception du dernier, ici NextID est NULL. Je connais l'identifiant du premier noeud.

Je veux les sélectionner tous dans le bon ordre, avec un identifiant de départ.

Est-il possible de faire cela dans T-SQL (Édition: SQL 2008) ou LINQ?

Je sais que je peux écrire du code pour le faire manuellement en C#, je me demande simplement si je peux déjà interroger dans cet ordre?

Répondre

5

Je ne suis pas sûr de [SortOrder] car je n'ai pas assez de données pour le tester. Cela vous permet de trier dans les deux sens.

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

C'est cool! '(cteList. [SortOrder] + 1)' devrait être juste '([SortOrder] + 1)' bien, sinon SQL se plaint que l'identificateur en plusieurs parties n'a pas pu être lié –

+0

Merci pour le commentaire! Pour certaines raisons, cela a fonctionné pour moi dans mssql 2005 enterprise manager quand j'ai écrit la requête. –

3

Quelle version de SQL Server? Si c'est en 2005 ou plus récent, vous pouvez utiliser un CTE récursif.

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

Joli travail avec le CTE. Il serait probablement bon d'éditer pour imposer l'ordre correct des lignes de résultat puisque 'UNION [ALL]' ne garantit pas un ordre particulier. –

+0

Intéressant, ça marche. Je l'ai modifié pour revenir en arrière (où id IS NULL, joindre sur ll.id = t.nextid), y a-t-il un moyen d'inverser le jeu de résultats? (juste curieux, je peux le faire aussi facilement dans LINQ) –

+0

@Phil: je me demandais juste si l'inscription ne garantirait pas la commande? Dans mon test, ça fonctionne très bien, mais je n'ai qu'un petit test pour le moment. –