您正在为线程化讨论板创建数据库架构的映像。有没有一种有效的方法为给定的线程选择正确排序的列表?我写的代码有效,但不按照我想要的方式排序。
假设您有这些数据:
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
任何帮助将不胜感激;谢谢!
<小时/> 更新
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 :(得分:8)
我相信你会爱这个。 我最近发现了Dense_Rank()函数,它是根据MSDN
用于“在结果集的分区内排名”的函数查看下面的代码以及“CommentID”的排序方式。
据我了解,您正在尝试按ParentCommentID对结果集进行分区。
注意“密集”栏目。
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
以下结果
答案 1 :(得分:1)
您必须使用hierarchyid(仅限sql2008)或一堆字符串(或字节)连接。
答案 2 :(得分:0)
我能想到的最好的方法是,如果你有一个将你的评论联系起来的父表(例如主题表)。如果你这样做,你应该能够简单地将你的回复加入到那里(显然你需要包含正确的列),然后你可以按主题ID,级别进行排序,以获得你所追求的排序顺序(或其他任何信息)主题表代表了一个很好的排序值。
答案 3 :(得分:0)
考虑在一个字段中存储整个层次结构(如果它发生变化,使用触发器更新它)。
您示例中的此字段包含: 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