Рекурсивный SQL CTE и пользовательский порядок сортировки - PullRequest
9 голосов
/ 19 февраля 2009

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

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

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

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

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

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

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

Вот CTE, которым я сейчас пользуюсь:

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 и раньше не слышал о типе иерархии. Прочитав об этом из этого комментария , я решил включить это в свой дизайн. Я поэкспериментирую с этим вечером и опубликую больше информации, если у меня будет успех.

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

Ответы [ 4 ]

8 голосов
/ 20 февраля 2009

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

Проверьте код ниже и как сортируется «CommentID».

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

Обратите внимание на столбец «dilrank».

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

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

1 голос
/ 07 июля 2009

Вы должны использовать иерархию (только sql2008) или связку строк (или байтов).

0 голосов
/ 19 февраля 2009

Подумайте о сохранении всей иерархии (с триггерами для ее обновления, если она изменится) в поле.

Это поле в вашем примере будет иметь: 1 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 голосов
/ 19 февраля 2009

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

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

...