Sql server 注释带有缩进的父子查询

Sql server 注释带有缩进的父子查询,sql-server,sql-server-2008,common-table-expression,Sql Server,Sql Server 2008,Common Table Expression,我一直在尝试以一种非常常见的博客方式检索文章的评论。以下是我的示例代码: -- ---------------------------- -- Sample Table structure for [dbo].[Comments] -- ---------------------------- CREATE TABLE [dbo].[Comments] ( [CommentID] int NOT NULL , [AddedDate] datetime NOT NULL , [AddedBy] n

我一直在尝试以一种非常常见的博客方式检索文章的评论。以下是我的示例代码:

-- ----------------------------
-- Sample Table structure for [dbo].[Comments]
-- ----------------------------
CREATE TABLE [dbo].[Comments] (
[CommentID] int NOT NULL ,
[AddedDate] datetime NOT NULL ,
[AddedBy] nvarchar(256) NOT NULL ,
[ArticleID] int NOT NULL ,
[Body] nvarchar(4000) NOT NULL ,
[parentCommentID] int NULL 
)


GO

-- ----------------------------
-- Sample Records of Comments
-- ----------------------------
INSERT INTO [dbo].[Comments] ([CommentID], [AddedDate], [AddedBy], [ArticleID], [Body],     [parentCommentID]) VALUES (N'1', N'2011-11-26 23:18:07.000', N'user', N'1', N'body', null);
GO
INSERT INTO [dbo].[Comments] ([CommentID], [AddedDate], [AddedBy], [ArticleID], [Body],   [parentCommentID]) VALUES (N'2', N'2011-11-26 23:18:50.000', N'user', N'2', N'body', null);
GO
INSERT INTO [dbo].[Comments] ([CommentID], [AddedDate], [AddedBy], [ArticleID], [Body],    [parentCommentID]) VALUES (N'3', N'2011-11-26 23:19:09.000', N'user', N'1', N'body', null);
GO
INSERT INTO [dbo].[Comments] ([CommentID], [AddedDate], [AddedBy], [ArticleID], [Body], [parentCommentID]) VALUES (N'4', N'2011-11-26 23:19:46.000', N'user', N'3', N'body', null);
GO
INSERT INTO [dbo].[Comments] ([CommentID], [AddedDate], [AddedBy], [ArticleID], [Body], [parentCommentID]) VALUES (N'5', N'2011-11-26 23:20:16.000', N'user', N'1', N'body', N'1');
GO
INSERT INTO [dbo].[Comments] ([CommentID], [AddedDate], [AddedBy], [ArticleID], [Body], [parentCommentID]) VALUES (N'6', N'2011-11-26 23:20:42.000', N'user', N'1', N'body', N'1');
GO
INSERT INTO [dbo].[Comments] ([CommentID], [AddedDate], [AddedBy], [ArticleID], [Body], [parentCommentID]) VALUES (N'7', N'2011-11-26 23:21:25.000', N'user', N'1', N'body', N'6');
GO

-- ----------------------------
-- Indexes structure for table Comments
-- ----------------------------

-- ----------------------------
-- Primary Key structure for table [dbo].[Comments]
-- ----------------------------
ALTER TABLE [dbo].[Comments] ADD PRIMARY KEY ([CommentID])
GO

-- ----------------------------
-- Foreign Key structure for table [dbo].[Comments]
-- ----------------------------
ALTER TABLE [dbo].[Comments] ADD FOREIGN KEY ([parentCommentID]) REFERENCES [dbo].   [Comments] ([CommentID]) ON DELETE NO ACTION ON UPDATE NO ACTION
GO
我想我可以使用CTE查询来完成如下工作:

WITH CommentsCTE(CommentID, AddedDate, AddedBy, ArticleID, Body, parentCommentID, lvl,  sortcol)
AS
(
SELECT CommentID, AddedDate, AddedBy, ArticleID, Body, parentCommentID, 0,   cast(CommentID as varbinary(max))
FROM Comments
UNION ALL
SELECT P.CommentID, P.AddedDate, P.AddedBy, P.ArticleID, P.Body, P.parentCommentID,    PP.lvl+1,
CAST(sortcol + CAST(P.CommentID AS BINARY(4)) AS VARBINARY(max))
FROM Comments AS P
JOIN CommentsCTE AS PP
ON P.parentCommentID = PP.CommentID
)
SELECT
REPLICATE('--', lvl)
+ right('>',lvl)+ AddedBy
+ ' :: '
+ Body,
CommentID,
parentCommentID,
lvl
FROM CommentsCTE
WHERE ArticleID = 1
order by sortcol
go
但到目前为止,结果非常令人失望,经过几天的调整后,我决定寻求帮助。我一直在寻找一种方法来显示文章的分层评论,就像在博客中一样

[编辑] 这个查询的问题是,我得到了重复的结果,因为我不知道如何正确地选择要显示注释的ArticleID。我还在寻找一种方法,可以在同一级别内按日期对子条目进行排序。 我试图实现的一个例子可能是:

(ArticleID[post retrieved])
-------------------------
-------------------------
(Comments[related to the article id above])
first comment[no parent]
--[first child to first comment]
--[second child to first comment]
----[first child to second child comment to first comment]
--[third child to first comment]
----[first child to third child comment to first comment]
------[(recursive child): first child to first child to third child comment to first comment]
------[(recursive child): second child to first child to third child comment to first comment]
second comment[no parent]
third comment[no parent]
--[first child to third comment]

我有点迷失在所有这些混乱中…我感谢任何帮助或更简单的方法来让这一切工作。谢谢

你非常接近。我对递归查询做了两个修改:

WITH CommentsCTE (CommentID, AddedDate, AddedBy, ArticleID, Body, parentCommentID, lvl, Thread)
AS
(
    SELECT  CommentID, 
            AddedDate, 
            AddedBy, 
            ArticleID, 
            Body, 
            parentCommentID, 
            0,
            ROW_NUMBER() over (order by CommentID) as Thread
    FROM @Comments
    where parentCommentID is null
    
    UNION ALL
    
    SELECT  P.CommentID, 
            P.AddedDate, 
            P.AddedBy, 
            P.ArticleID, 
            P.Body, 
            P.parentCommentID,    
            PP.lvl+1,
            PP.Thread
    FROM @Comments AS P
    JOIN CommentsCTE AS PP ON P.parentCommentID = PP.CommentID
)
SELECT  REPLICATE('--', lvl) + right('>',lvl)+ AddedBy + ' :: ' + Body,
        CommentID,
        parentCommentID,
        lvl,
        AddedDate,
        Thread
FROM CommentsCTE
WHERE ArticleID = 1
order by Thread, CommentID
首先,加入

where parentCommentID is null
到你的锚查询消除你的重复。其次,为了正确地对它们进行排序,您需要一个线程标识符。我在锚查询中添加了一个行号来创建线程号。这允许您对结果进行正确排序


如何让人失望?您当前的结果与您希望得到的结果有何不同?好吧,从该查询中,我得到了不应该存在的重复结果,并且无法确定如何以正确的方式按日期排序评论。非常非常感谢。这似乎正是我一直在寻找的。它将被广泛测试,我可能会在将来报告更多的反馈。