2011-04-16 76 views
3

在我的个人资料网站上,用户可以发表评论,并对评论发表评论(像facebook一样)。我正在实施一些分页,因为在1个配置文件中可能会有数千条评论。分页工作,但是,由于有孩子的评论,一个简单的顶部n查询打破了对话。我只想分析父母的意见,而不是孩子。如何更有效地编写此查询?

表“意见” 其中有:

- commentID 
- commentText 
- parentCommentID 
- commentOnUserID 

这里的问题是,我想只有在那些父母的意见进行分页(parentCommentID = 0)。所以我写了一个查询,如:

select * from Comments c 
where c.parentCommentID = 0 
and c.commentOnUserID = 65939 

(我离开了实际的分页查询,因为这是不相关)

,但我也想加载所有这些评论的孩子的,孩子是还有一条评论,但随后与parentCommentID =一些评论ID:

select * from comments c 
where c.parentCommentID in (* get the commentId's from the previous query) 
and c.commentOnUserID = 65939 

有没有办法有效地结合两个在1查询?

回答

2
declare @T table(commentID int, 
       commentText varchar(max), 
       parentCommentID int, 
       commentOnUserID int) 

insert into @T values 
(1, 'Comment 1', 0, 1), 
(2, 'Comment 2', 0, 1), 
(3, 'Comment 3', 0, 1), 
(4, 'Comment 4 sub 1', 1, 1), 
(5, 'Comment 5 sub 1', 1, 1), 
(6, 'Comment 6 sub 1', 1, 1), 
(7, 'Comment 1 sub 2', 2, 1), 
(8, 'Comment 1 sub 2', 2, 1), 
(9, 'Comment 1 sub 3', 3, 1) 

declare @UserID int = 1 

;with cte as 
(
    select 
    T.commentID, 
    T.CommentText, 
    row_number() over(order by commentID) as rn 
    from @T as T 
    where 
    T.parentCommentID = 0 and 
    T.commentOnUserID = @UserID 
    union all 
    select 
    T.commentID, 
    T.CommentText, 
    C.rn 
    from @T as T 
    inner join cte as C 
     on T.parentCommentID = C.commentID 
) 
select * 
from cte 
where rn between 1 and 2 -- use rn for pagination 
order by rn, commentID 

结果

commentID parentCommentID CommentText   rn 
----------- --------------- -------------------- -------------------- 
1   0    Comment 1   1 
4   1    Comment 4 sub 1  1 
5   1    Comment 5 sub 1  1 
6   1    Comment 6 sub 1  1 
2   0    Comment 2   2 
7   2    Comment 1 sub 2  2 
8   2    Comment 1 sub 2  2 
1

事情是这样的:

WITH 
    ParentComment AS (
     SELECT * from Comments c 
     WHERE c.parentCommentID = 0 
     AND c.commentOnUserID = 65939 
    ) 
SELECT * 
FROM Comments c 
WHERE c.commentOnUserID = 65939 
AND (
    c.CommentID IN (SELECT CommentID FROM ParentComment) 
    OR c.ParentCommentID IN (SELECT CommentID FROM ParentComment) 
) 

没有测试在SQL Server中的语法,但应该是一般的想法。

0

我会做这在类似如下的方式:

SELECT p.*, c.* 
FROM comment c LEFT JOIN comment p ON (c.parentCommentID = p.commentID) 
WHERE p.parentCommentID = 0 
AND p.commentOnUserID = 65939 

我敢肯定有一些办法,包括在子女的父或母,结果很好,但我知道在MySQL中至少有性能问题在加入条件下放置一个OR。