【问题标题】:SQL Query logic for order by排序依据的 SQL 查询逻辑
【发布时间】:2016-12-30 13:40:44
【问题描述】:

我遇到了在 SQL 查询中按逻辑创建订单的问题:

查询如下:

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;

它显示以下结果:

但预期的结果是:

变化是,我需要在commentid - 144之后插入记录,因为回复commentid和commentid是一样的。

意味着只要有匹配的 commentid 和 replycommentid ,在本例中是 144,那么带有 replycommentid 的行应该下降到带有 commentid 144 的行。

答案的查询列表:

【问题讨论】:

  • 这个新订单背后的逻辑是什么?
  • 订单应该和我最初的查询一样,如果replyid匹配则需要插入,现在插入发生在最后一个,现有订单不应该改变它应该保持不变
  • 试着用文字写下你想要的。关于查询的输出顺序,仅保证ORDER BY 子句中指定的顺序。否则,如果SQL-Server 选择不同的执行计划,您可能会得到不同的结果顺序,即使对于相同的查询也是如此。
  • 另外,避免使用“insert”,除非您实际上是在谈论inserting。由于您是在选择而不是插入,因此很混乱。

标签: sql .net sql-server tsql logic


【解决方案1】:

如何按照父记录的commentID字符串与当前记录组合排序

WITH CTE AS ( SELECT CommentID ,
                CommentUserName,
                 ReplyCommentID ,
                CommentID AS ThreadID ,
                CAST( CommentID AS VARCHAR( MAX ) ) AS PathStr,
                HtmlComment ,
                CommentPostDocumentID ,
                 CommentIsApproved,
                CommentDate ,
                CAST('' AS VARCHAR(MAX)) AS NewPathStr -- added
         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,              
                CTE.NewPathStr+'--'+CAST(cte.CommentID AS VARCHAR(MAX)) + '-' + CAST(t.CommentID AS VARCHAR(MAX)) AS NewPathStr  --added
         FROM Blog_CommentDetails AS T WITH(NOLOCK)
         JOIN CTE 
         ON T.ReplyCommentID = CTE.CommentID
         WHERE T.ReplyCommentID IS NOT NULL)

SELECT *  -- You might have to remove NewpathStr if you do not want to see it
    FROM CTE
    WHERE CommentPostDocumentID = 15 AND CommentIsApproved=1
    ORDER BY ThreadID, NewPathStr, PathStr ,
            CommentDate DESC;

【讨论】:

  • 哎呀。忘了空字符串和空字符串是不同的。 @SmartestVEGA 已修复。
  • 现在我的要求是列出很好,这是在144之后插入replycommentid 144,但是查询的顺序已经折腾了,匹配的两条记录被插入到最后一个位置和倒数第二个位置,理想情况下它应该在第二和第三位置
【解决方案2】:

这是深度优先的方法,可以使用 ORDER BY hierarchyid 值来完成,因此:

(1) 订购方式 线程 ID, CONVERT(HIERARCHYID, '\' + REPLACE(PathStr, '-', '\') + '\'), 评论日期

(2) 在递归 CTE 中,我将生成 PathStr 作为 hirarchyid 值。

注意:我没有测试过这个解决方案。 注意 #2:抱歉格式错误:我正在手机上写这个答案。

【讨论】:

    猜你喜欢
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    相关资源
    最近更新 更多