2011-11-27 86 views
3

我一直在嘗試以相當常見的博客時尚方式檢索文章評論。這裏是我的示例代碼:評論帶縮進的父子查詢

-- ---------------------------- 
-- 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

令人失望的是如何?你目前的結果與你想要得到的結果有什麼不同? – Bert

+0

好吧,從那個查詢我得到的重複,不應該在那裏,並不能找出如何以適當的方式按日期排序評論。 – poldoj

回答

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 

到你的錨查詢消除重複的內容。其次,要正確地對它們進行排序,您需要一個線程標識符。我在你的錨點查詢中添加了一個行號來創建線程號。這可以讓你正確地排序結果。

Here is an example of it in action.

+0

很多很多很多謝謝。這似乎正是我一直在尋找的。它將被廣泛測試,我可能會在未來報告更多反饋。 – poldoj