我有三列
ThreadID
DateTime
CommentID
ReplyCommentID
查询
WITH CTE AS ( SELECT CommentID ,
CommentUserName,
ReplyCommentID ,
CommentID AS ThreadID ,
CAST( CommentID AS VARCHAR( MAX ) ) AS PathStr,
HtmlComment ,
CommentPostDocumentID ,
CommentIsApproved,
CommentDate
FROM Blog_CommentDetails AS T WITH(NOLOCK)
WHERE ReplyCommentID IS NULL
UNION ALL
SELECT T.CommentID ,
T.CommentUserName,
T.ReplyCommentID ,
CTE.ThreadID ,
PathStr + '-'+ CAST( T.ReplyCommentID AS VARCHAR( MAX ) ) AS PathStr,
T.HtmlComment ,
t.CommentPostDocumentID ,
t.CommentIsApproved,
T.CommentDate
FROM Blog_CommentDetails AS T WITH(NOLOCK)
JOIN CTE
ON T.ReplyCommentID = CTE.CommentID
WHERE T.ReplyCommentID IS NOT NULL)
SELECT *
FROM CTE
WHERE CommentPostDocumentID = 15 AND CommentIsApproved=1
ORDER BY ThreadID, PathStr ,
CommentDate DESC;
我需要先通过ThreadID升序排序 然后我需要按CommentID升序排序 然后我需要按日期降序排序第三 但有一个条件,当有两行的commenid和replycommendid匹配时,应该首先使用commenid行。
我如何为此编写订单?
ORDER BY ThreadID,CommentID,DateTime desc,
IF(ReplyCommentID == CommentID)
then
rows with commentid should be first
目前的结果:
答案 0 :(得分:0)
您可以使用计算值进行排序;但是,由于计算需要来自单独行的属性,因此首先要组合这些行。 如果没有文本形式的演示数据,我可以接管我的环境,那么测试就有点难了。
如果我们认为a
代表CommentId
而b
代表ReplyCommentID
,则以下架构非常接近您的要求:
create table test (
a int,
b int
);
insert into test (a,b) values (1,null), (2,1), (3,2), (4,1);
select distinct test.a as a, test.b as b, case when (test.b=test2.a or test.b is null) then 0 else 1 end as priority
from test left join test test2 on test.b = test2.a and test2.b is null
order by priority,a,b
请注意,与order by a,b
相比的订单与您在样本数据中的预期类似。
Givent在申请查询时(在WITH CTE...
- 部分之后),它应该如下所示。如上所述,我无法测试它,所以如果它不能立即起作用,请不要向我扔石头:
SELECT distinct cte.*, case when (cte.ReplyCommentID =cte2.CommentId or cte.ReplyCommentID is null) then 0 else 1 end as priority
FROM CTE left join CTE cte2 on cte.ReplyCommentID = cte2.CommentId and cte2.ReplyCommentID is null
WHERE CommentPostDocumentID = 15 AND CommentIsApproved=1
ORDER BY ThreadID, priority, CommentId, PathStr , CommentDate DESC;
答案 1 :(得分:0)
以下大量示例将介绍基于CommentID
和ReplyCommentID
(用作ParentID
)的评论树。同一ReplyCommentID
的孩子按CommentDate DESC
排序:
DECLARE @Table TABLE (
CommentID INT,
ReplyCommentID INT,
CommentDate DATETIME
);
INSERT INTO @Table VALUES
(140,NULL, CAST('20170109' AS DATETIME))
,(141,NULL, CAST('20170110' AS DATETIME))
,(142,141, CAST('20170111' AS DATETIME))
,(143,141, CAST('20170112' AS DATETIME))
,(144,141, CAST('20170113' AS DATETIME))
,(145,144, CAST('20170114' AS DATETIME))
,(146,NULL, CAST('20170115' AS DATETIME));
WITH [Statistics] AS (
SELECT Records.CommentID, Records.ReplyCommentID
, COUNT(Children.CommentID) AS NrOfChildren
, ROW_NUMBER() OVER (PARTITION BY Records.ReplyCommentID ORDER BY Records.CommentDate DESC) AS NthChild
, COUNT(Records.CommentID) OVER (PARTITION BY Records.ReplyCommentID) AS NrOfSiblings
FROM @Table Records
LEFT JOIN @Table Children ON Records.CommentID = Children.ReplyCommentID
GROUP BY Records.CommentID, Records.ReplyCommentID, Records.CommentDate
)
, Tree AS (
SELECT *
, 1 AS [Order]
, 0 AS [Rerouting]
, CAST(-1 AS INT) AS ReroutedFromNthChild
FROM [Statistics] AS TreeNode
WHERE ReplyCommentID IS NULL AND NthChild = 1
UNION ALL
SELECT NextNode.*
, TreeNode.[Order] + 1 AS [Order]
, CASE
WHEN (TreeNode.NrOfChildren = 0 AND TreeNode.NthChild = TreeNode.NrOfSiblings AND TreeNode.ReplyCommentID = NextNode.CommentID)
OR (TreeNode.Rerouting = 1 AND TreeNode.ReroutedFromNthChild = TreeNode.NrOfChildren AND TreeNode.ReplyCommentID = NextNode.CommentID)
THEN 1
ELSE 0
END AS [Rerouting]
, CAST(TreeNode.NthChild AS INT) AS ReroutedFromNthChild
FROM Tree AS TreeNode
JOIN [Statistics] AS NextNode
--Has children, so select first child
ON (TreeNode.Rerouting = 0 AND TreeNode.NrOfChildren > 0 AND NextNode.NthChild = 1 AND TreeNode.CommentID = NextNode.ReplyCommentID)
--Has no children, so select next sibling
OR (TreeNode.Rerouting = 0 AND TreeNode.NrOfChildren = 0 AND TreeNode.NthChild + 1 = NextNode.NthChild AND (TreeNode.ReplyCommentID = NextNode.ReplyCommentID OR (TreeNode.ReplyCommentID IS NULL AND NextNode.ReplyCommentID IS NULL)))
--Has no children or following siblings, so retrace the step (reroute)
OR (TreeNode.Rerouting = 0 AND TreeNode.NrOfChildren = 0 AND TreeNode.NthChild = TreeNode.NrOfSiblings AND TreeNode.ReplyCommentID = NextNode.CommentID)
--Was rerouting but has children, so back on track and follow the next child
OR (TreeNode.Rerouting = 1 AND TreeNode.ReroutedFromNthChild < TreeNode.NrOfChildren AND TreeNode.ReroutedFromNthChild + 1 = NextNode.NthChild AND TreeNode.CommentID = NextNode.ReplyCommentID)
--Was rerouting and has no other children, so continue rerouting
OR (TreeNode.Rerouting = 1 AND TreeNode.ReroutedFromNthChild = TreeNode.NrOfChildren AND TreeNode.ReplyCommentID = NextNode.CommentID)
--Rerouted to the top without children left, jumping to the next sibling
OR (TreeNode.Rerouting = 1 AND (TreeNode.ReroutedFromNthChild = TreeNode.NrOfChildren OR TreeNode.NrOfChildren = 0) AND TreeNode.NthChild + 1 = NextNode.NthChild AND TreeNode.ReplyCommentID IS NULL AND NextNode.ReplyCommentID IS NULL)
)
select *
from Tree
where Rerouting = 0
ORDER BY [Order]