我一直试图以一种非常常见的博客时尚方式检索文章评论。这是我的示例代码:
-- ----------------------------
-- 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]
我有点迷失在所有这些混乱中...我感谢任何帮助或更简单的方法让这个工作。感谢
答案 0 :(得分:4)
你非常接近。我对递归查询做了两处修改:
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
到您的锚点查询可以消除重复项。其次,要正确排序它们,您需要一个线程标识符。我在您的锚点查询中添加了一个行号来创建线程号。这允许您正确地对结果进行排序。