2009-02-19 2 views
9

Изображение Вы создаете схему БД для многопоточной дискуссионной панели. Есть ли эффективный способ выбора правильно отсортированного списка для данного потока? Код, который я написал, работает, но не сортирует так, как мне бы хотелось.Рекурсивный SQL CTE и пользовательское упорядочение сортировки

Допустим, у вас есть эти данные:

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

Так структура должна выглядеть следующим образом:

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

В идеале, в коде, мы хотим, чтобы результирующий набор появится в следующий порядок: 1, 2, 3, 5, 4
ПРОБЛЕМЫ: с СТ я написал это на самом деле возвращается как: 1, 2, 4, 3, 5

Я знаю, что это было бы легко сгруппировать/заказать с помощью LINQ, но я неохотно делаю это в памяти. Похоже, что лучшим решением в этой точке, хотя ...

Здесь КТР настоящее время я использую:

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 

Любая помощь будет оценена; Благодаря!



Я новичок в SQL и раньше не слышал об иерархическом типе данных. Прочитав об этом от this comment, я решил, что могу включить это в свой дизайн. Я буду экспериментировать с этим сегодня вечером и опубликовать дополнительную информацию, если у меня будет успех.


Update
Возвращается результат из моих выборочных данных, используя предложение 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

боги sql возмущены вашими требованиями – Shawn

ответ

0

Hmmmm - Я не уверен, что если ваша структура лучше всего подходит для этой задачи. В верхней части головы я не могу придумать, как отсортировать данные по вашему желанию в рамках вышеуказанного запроса.

Лучшее, о чем я могу думать, это если у вас есть родительская таблица, которая связывает ваши комментарии вместе (например, таблицу тем). Если вы это сделаете, вы должны просто присоединиться к своим ответам на это (вам нужно будет указать правильный столбец, очевидно), а затем вы можете отсортировать по topicID, Level, чтобы получить порядок сортировки, по которому вы находитесь (или любую другую информацию по таблица тем представляет собой хорошее значение для сортировки).

0

Рассмотрите возможность хранения всей иерархии (с помощью триггеров для ее обновления, если она изменяется) в поле.

Это поле в вашем примере будет иметь: 1,2 1.2.3 1.2.5 1,4

тогда вы просто должны сортировать на этом поле, попробовать это и увидеть:

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

да - это называется материализованным путем –

8

Я уверен, что вы будете love это. Недавно я узнать о Dense_Rank() функцию, которая для «ранжирования в перегородке результирующего набора» в соответствии с MSDN

Выезд ниже код и как «CommentID» сортируется.

Насколько я понимаю, вы пытаетесь разбить свой результирующий набор на ParentCommentID.

Обратите внимание на колонку "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

Результат ниже

+0

Спасибо за предложение, я пытался заставить dense_rank() работать сначала без везения. Я запросил ваш код на своих образцах данных, и это сработало ... почти. Один ряд был не в порядке. Я опубликую данные выше. –

1

Вы должны использовать `hierarchyid` (только SQL2008) или связка строки (или байт) конкатенации.

Смежные вопросы