如何使用 SQL 查询像父子一样显示层次结构行

2024-02-06

我在我的应用程序中使用博客评论,其中我将每个评论行插入一个表中,这样如果其中任何一个评论对单击的特定评论进行回复commentid我插入为replyid在新行中。

下面是屏幕截图:

在这里你可以看到commentid24 和 26 有replycommentid23. 我需要一个查询来显示 23 之后的 24 和 26。因为 23 是 24 和 26 的父级。

以下是表布局和示例数据的设置脚本:

USE [myDB]
GO
/****** Object:  Table [dbo].[Blog_CommentDetails]    Script Date: 11/12/2016 6:36:04 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Blog_CommentDetails](
    [CommentID] [int] IDENTITY(1,1) NOT NULL,
    [CommentUserName] [nvarchar](200) NOT NULL,
    [CommentText] [nvarchar](max) NULL,
    [CommentApprovedByUserID] [int] NULL,
    [CommentPostDocumentID] [int] NOT NULL,
    [CommentDate] [datetime] NULL DEFAULT (getdate()),
    [HtmlComment] [nvarchar](max) NULL,
    [CommentIsSpam] [bit] NULL CONSTRAINT [DEFAULT_Blog_MainComment_CommentIsSpam]  DEFAULT ((0)),
    [CommentIsApproved] [bit] NULL CONSTRAINT [DEFAULT_Blog_MainComment_CommentIsApproved]  DEFAULT ((0)),
    [CommentEmail] [nvarchar](250) NULL,
    [CommentInfo] [nvarchar](max) NULL,
    [ReplyCommentID] [int] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
SET IDENTITY_INSERT [dbo].[Blog_CommentDetails] ON 

GO
INSERT [dbo].[Blog_CommentDetails] ([CommentID], [CommentUserName], [CommentText], [CommentApprovedByUserID], [CommentPostDocumentID], [CommentDate], [HtmlComment], [CommentIsSpam], [CommentIsApproved], [CommentEmail], [CommentInfo], [ReplyCommentID]) VALUES (22, N'Vikash', N'This is main comment', NULL, 1, CAST(N'2016-11-12 17:36:25.637' AS DateTime), N'<div class="main-comment-section"><div class="row"><div class="col-xs-12"><div class="post-comment-section"><p id="pCommentorName"><span id="sCommentorName" class="blogcommentname">Vikash</span><span id="sBlogPostedDate">Nov12,2016 5:35PM</span></p><p class="comment-detail" id="pBlogCommentDetails">This is main comment</p><div class="comment-reply"><ul><li><img src="assets/svg/components/blog-detail/icon_reply.svg" alt="Reply comment icon"><a class="joinus-link" id="btnComment" href="#" target="_self">::blogdetailsReply</a></li></ul></div></div></div></div></div>', 0, 1, N'[email protected] /cdn-cgi/l/email-protection', NULL, NULL)
GO
INSERT [dbo].[Blog_CommentDetails] ([CommentID], [CommentUserName], [CommentText], [CommentApprovedByUserID], [CommentPostDocumentID], [CommentDate], [HtmlComment], [CommentIsSpam], [CommentIsApproved], [CommentEmail], [CommentInfo], [ReplyCommentID]) VALUES (23, N'Megha k', N'This is reply comment', NULL, 1, CAST(N'2016-11-12 17:39:04.250' AS DateTime), N'<div class="reply-comment-section"><div class="row"><div class="col-xs-12"><div class="post-comment-section"><p id="pBlogReplyCommentorName"><span id="sReplyCommentorName" class="blogcommentname">Megha k</span><span id="sBlogReplyCommentDate">Nov12,2016 5:38PM</span></p><p class="comment-detail" id="pBlogReplyCommentDetails">This is reply comment</p><div class="comment-reply"><ul><li><img class="contributors-list" src="assets/svg/components/blog-detail/icon_reply.svg" alt="Reply comment icon"><a class="joinus-link" id="btnCommentReply" href="#" target="_self">::blogdetailsReply</a></li></ul></div></div></div></div></div>', 0, 1, N'[email protected] /cdn-cgi/l/email-protection', NULL, NULL)
GO
INSERT [dbo].[Blog_CommentDetails] ([CommentID], [CommentUserName], [CommentText], [CommentApprovedByUserID], [CommentPostDocumentID], [CommentDate], [HtmlComment], [CommentIsSpam], [CommentIsApproved], [CommentEmail], [CommentInfo], [ReplyCommentID]) VALUES (24, N'Siddappa H', N'This is reply text.', NULL, 1, CAST(N'2016-11-12 17:39:58.847' AS DateTime), N'<div class="main-comment-section"><div class="row"><div class="col-xs-12"><div class="post-comment-section"><p id="pCommentorName"><span id="sCommentorName" class="blogcommentname">Siddappa H</span><span id="sBlogPostedDate">Nov12,2016 5:39PM</span></p><p class="comment-detail" id="pBlogCommentDetails">This is reply text.</p><div class="comment-reply"><ul><li><img src="assets/svg/components/blog-detail/icon_reply.svg" alt="Reply comment icon"><a class="joinus-link" id="btnComment" href="#" target="_self">::blogdetailsReply</a></li></ul></div></div></div></div></div>', 0, 1, N'[email protected] /cdn-cgi/l/email-protection', NULL, 23)
GO
INSERT [dbo].[Blog_CommentDetails] ([CommentID], [CommentUserName], [CommentText], [CommentApprovedByUserID], [CommentPostDocumentID], [CommentDate], [HtmlComment], [CommentIsSpam], [CommentIsApproved], [CommentEmail], [CommentInfo], [ReplyCommentID]) VALUES (25, N'Suresh P', N'This is reply comment', NULL, 1, CAST(N'2016-11-12 17:40:44.470' AS DateTime), N'<div class="reply-comment-section"><div class="row"><div class="col-xs-12"><div class="post-comment-section"><p id="pBlogReplyCommentorName"><span id="sReplyCommentorName" class="blogcommentname">Suresh P</span><span id="sBlogReplyCommentDate">Nov12,2016 5:40PM</span></p><p class="comment-detail" id="pBlogReplyCommentDetails">This is reply comment</p><div class="comment-reply"><ul><li><img class="contributors-list" src="assets/svg/components/blog-detail/icon_reply.svg" alt="Reply comment icon"><a class="joinus-link" id="btnCommentReply" href="#" target="_self">::blogdetailsReply</a></li></ul></div></div></div></div></div>', 0, 1, N'[email protected] /cdn-cgi/l/email-protection', NULL, NULL)
GO
INSERT [dbo].[Blog_CommentDetails] ([CommentID], [CommentUserName], [CommentText], [CommentApprovedByUserID], [CommentPostDocumentID], [CommentDate], [HtmlComment], [CommentIsSpam], [CommentIsApproved], [CommentEmail], [CommentInfo], [ReplyCommentID]) VALUES (26, N'Vikash', N'This is reply text', NULL, 1, CAST(N'2016-11-12 17:41:44.673' AS DateTime), N'<div class="reply-comment-section"><div class="row"><div class="col-xs-12"><div class="post-comment-section"><p id="pBlogReplyCommentorName"><span id="sReplyCommentorName" class="blogcommentname">Vikash</span><span id="sBlogReplyCommentDate">Nov12,2016 5:40PM</span></p><p class="comment-detail" id="pBlogReplyCommentDetails">This is reply text</p><div class="comment-reply"><ul><li><img class="contributors-list" src="assets/svg/components/blog-detail/icon_reply.svg" alt="Reply comment icon"><a class="joinus-link" id="btnCommentReply" href="#" target="_self">::blogdetailsReply</a></li></ul></div></div></div></div></div>', 0, 1, N'[email protected] /cdn-cgi/l/email-protection', NULL, 23)
GO
SET IDENTITY_INSERT [dbo].[Blog_CommentDetails] OFF
GO

欢迎所有建议!

我还在下面添加了三个插入查询:

Valex,请将此查询插入“INSERT [dbo].[Blog_CommentDetails] ([CommentID], [CommentUserName], [CommentText], [CommentApprovedByUserID], [CommentPostDocumentID], [CommentDate], [HtmlComment], [ CommentIsSpam]、[CommentIsApproved]、[CommentEmail]、[CommentInfo]、[ReplyCommentID]、[IsRejected]) 值 (58、N'Vicky'、N'Test'、0、1、CAST(N'2016-12-02) 11:51:07.270' AS DateTime), N'VickyDec2,2016 11:47AM

Test

如果您想要完整的层次结构,甚至是其中的一部分,请按照正确的顺序

编辑 - 删除 2008 年的 Concat()

Declare @Top  int = 23 --null             --<<  Sets top of Hier Try 23
Declare @Nest varchar(25) ='|-----'  --<<  Optional: Added for readability

;with cteP as (
      Select Seq  = cast(1000+Row_Number() over (Order by CommentID) as varchar(500))
            ,CommentID
            ,ReplyCommentID
            ,Lvl=1
      From   [dbo].[Blog_CommentDetails]
      Where  IsNull(@Top,-1) = case when @Top is null then isnull(ReplyCommentID,-1) else CommentID end
      Union  All
      Select Seq  = cast(p.Seq+'.'+cast(1000+Row_Number() over (Order by r.CommentID) as varchar(25)) as varchar(500))
            ,r.CommentID
            ,r.ReplyCommentID
            ,p.Lvl+1
      From   [dbo].[Blog_CommentDetails] r 
      Join   cteP p on r.ReplyCommentID = p.CommentID)
     ,cteR1 as (Select *,R1=Row_Number() over (Order By Seq) From cteP)
     ,cteR2 as (Select A.Seq,A.CommentID,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.CommentID )
Select A.R1  
      ,B.R2
      ,A.CommentID
      ,A.ReplyCommentID
      ,A.Lvl
      ,CommentText = Replicate(@Nest,A.Lvl-1) + C.CommentText
      -- Include any other fields from [dbo].[Blog_CommentDetails] alias C
 From cteR1 A 
 Join cteR2 B on A.CommentID=B.CommentID
 Join [dbo].[Blog_CommentDetails] C on A.CommentID=C.CommentID
 Order By A.R1

Returns

如果 @Top 设置为 23(例如),则返回将为

我应该补充一点,cteR2 不是必需的,但它确实表明范围和/或父级或叶级。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 SQL 查询像父子一样显示层次结构行 的相关文章

  • 如何确定给定的表是否是内存优化的?

    早上好 我的第一个问题是如何确定在 MS SQL Server 中创建的表是否是内存优化的 我有一些表 但我不记得我创建的其中一些表是否经过内存优化 非常感谢您的回答 为了重复这里的另一个答案 这是一种获取状态的方法all数据库中的表 se
  • SQL Server 与 Oracle DBMS_METADATA.GET_DDL 并行吗?

    我正在寻找命令行或脚本化解决方案来从 SQL Server 2005 中为所有数据库对象提取 DDL 表 存储过程 视图 索引 索引 约束等 GUI 工具不感兴趣 优先选择内置工具 因为它最能与 Oracle 的 DBMS METADATA
  • 连接到 SQL Server 数据库 C#-WinForms

    我正在制作一个桌面应用程序 我希望用户必须登录才能充分使用该程序 我已经在 www winhost com 我的网站的托管位置 上创建了一个数据库 但现在我不知道该怎么办 我一直在使用 google 和 msdn 我想知道如何以编程方式将新
  • SQL Server中根据条件进行计数

    有谁知道如何在 SQL Server 中根据条件进行计数 Example 如何对表中名称为 system 的记录以及 CaseID 记录总数进行列计数 顾客表 UserID CaseID Name 1 100 alan 1 101 alan
  • 针对 SQL Server 的 SQL 查询的执行日期时间

    我曾经发现过这个很好的查询here https dba stackexchange com a 135080 43889 我想将查询的执行时间添加到以下查询中 USE master go SELECT sdest DatabaseName
  • SQL Server 查看主键

    有没有办法在 sql server 中为视图提供主键 我知道在oracle中这是可能的 我不关心更新它的只读视图 但其他人正在 ms access 中使用它 所以我希望显示我知道正确的约束 是的 您可以创建一个索引视图 http msdn
  • 在 Sql Server 2005 中实现最后修改列的最佳方法?

    如何在 SQL 中实现最后修改列 我知道对于创建日期的列 您可以将默认值设置为getdate 对于最后修改我一直使用触发器 但似乎必须有更好的方法 Thanks 触发器是最好的方法 因为此逻辑与表密切相关 而不是与应用程序相关 除了更细粒度
  • 从存储过程执行SQL Server代理作业并返回作业结果

    需要有一个存储过程来调用 SQL Server 代理作业并返回作业是否成功运行 到目前为止我已经 CREATE PROCEDURE MonthlyData AS EXEC msdb dbo sp start job N MonthlyDat
  • 从 SQL Server 的表中“流式”读取超过 1000 万行

    以流方式 如 SQL Server Management Studio 那样 从表 在 SQL Server 2012 中 BI 实例 读取数百万条记录的最佳策略是什么 我需要在本地缓存这些记录 C 控制台应用程序 以进行进一步处理 Upd
  • 如何更改隔离级别?

    我正在使用 EF 4 0 并且我想使用隔离级别serializable 因为在事务中我想在读取时阻止寄存器 好吧 在 SQL Server 中 我尝试使用以下命令更改隔离级别 SET TRANSACTION ISOLATION LEVEL
  • 为什么需要 EndExecuteNonQuery()?

    文档here http msdn microsoft com en us library ca56w9se aspx指出 开发人员必须致电 EndExecuteNonQuery 方法完成 操作 我无法找到一个充分的理由来解释为什么会这样 或
  • 如何将可变数量的参数传递给 SQL Server 存储过程?

    我将 SQL Server 2005 用于我的小型 Web 应用程序 我想将参数传递给 SP 但有一个条件 可以不时更改的参数数量 想一想 这次我传递姓名和地址 下次我传递姓名 地址 该参数范围可以是 1 30 您使用默认参数声明该过程 并
  • 如何在 SQL Server 2005 中使用存储过程使用 CTE 从分层数据中获取所有子项及其自身

    我有很多类似的结构表 如下所示 CREATE TABLE dbo tbl Hierarchy ID int NOT NULL ParentID int NOT NULL Text nvarchar 100 NOT NULL other fi
  • 表值函数降低了我的查询性能

    今天我在尝试让查询按照我期望的方式执行时经历了一段可怕的时光 我不得不对昨天查询中的表值函数进行轻微更改 该更改对查询产生了巨大的性能影响 在评估执行计划并查看统计 IO 和时间后 我发现因为我更改了函数以返回表变量而不仅仅是结果集 所以它
  • SQL Server 2008 中超前滞后函数的替代

    我想将当前行与下一行中的值进行比较 SQL 有LEAD and LAG函数来获取下一个和上一个值 但我无法使用它们 因为我使用的是 SQL Server 2008 那么我该如何得到这个呢 我有带输出的表 Id ActId StatusId
  • 如何为多用户应用程序实现简单的锁定机制?

    我真的不想在这里重新发明井 所以我寻求在多用户数据库应用程序中实现简单 行 锁定机制的想法 假设我有一个名为Products其中当然有一个ID PK 还有一个rowversion列 到目前为止尚未使用 我只想允许one用户能够编辑特定行 当
  • 我们可以在 Azure 上的 T-SQL 过程中创建数据库范围的凭据吗

    我们可以在 Azure SQL 上的 T SQL 过程中为共享访问签名创建数据库范围的凭据吗 我们正在尝试从存储在 Azure blob 上的 csv 文件批量插入数据 以下是步骤 使用 JAVA 创建 SAS 凭证 Java将调用存储过程
  • 检查 SQL MAX() 函数返回 null

    我的问题是 如果我的表为空或者我使用 max 函数的列没有我指定的值 那么为什么 sqlDataReader hasRows TRUE 它给出了空记录 我该如何解决这个问题 提前致谢 像 MAX 这样的聚合函数将始终为每组返回一行 就您而言
  • 将 XML 文件读取到已存在的数据库表中

    我正在尝试将 XML 文件读入已存在的数据库表中 问题是 XML 标签和数据库列的名称不同 尽管它们具有相同的数据类型 因此 我想将 XML 标签 翻译 到数据库列中 以便可以输入数据库 不过我不知道该怎么做 这是我到目前为止所做的 sta
  • 为什么我要费心使用全文搜索?

    我是全文搜索新手 我使用了以下查询 Select From Students Where FullName LIKE abc 学生表包含数百万条记录 所有记录都是随机的 如下所示 QZAQHIEK VABCNLRM KFFZJYUU 仅用了

随机推荐