【问题标题】:Insert a row between two rows in SQL在 SQL 的两行之间插入一行
【发布时间】:2016-12-02 07:59:50
【问题描述】:

我有一个这样的表格,它显示了哪个用户评论了哪个父线程。

ParentID  CommentID UserName  CommentDateTime
58         58       Vicky     2016-12-02 11:51:07.270
58         61       Billu     2016-12-02 12:35:40.220
58         62       Rakesh    2016-12-02 12:37:42.133

如果假设对第 2 行进行了评论,则会生成一个新的 commentid,即 63

我想编写一个按以下顺序列出行的 sql 查询:

ParentID  CommentID UserName  CommentDateTime
58         58       Vicky     2016-12-02 11:51:07.270
58         61       Billu     2016-12-02 12:35:40.220
61         63       Rakesh    2016-12-02 13:37:42.133
58         62       Rakesh    2016-12-02 12:37:42.133

你能帮我写一个逻辑/SQL吗?

【问题讨论】:

  • 给定的父评论可以有多少回复?回复的数量是否可变?
  • SQL 数据本质上是无序的 - 所以你不能在两个现有行之间插入一行 - 只能将它添加到表的末尾。当您从表中选择数据并明确指定 ORDER BY 子句时,您只会得到一个 order ...
  • 您可以删除现有的并通过使用临时表的排列重新进入。
  • @Suraz 在检索数据时仍需要对其进行隐式排序。 SQL Server 不保证顺序,否则
  • Sql Server按主键顺序插入行并按主键顺序检索行(如果未指定order by

标签: sql sql-server tsql stored-procedures logic


【解决方案1】:

如果我做对了,您希望按所需顺序输出记录,而不是将它们插入表中。在这里,我们看到了一个帖子树,所以我认为您应该使用recursive CTE。对于每个节点,我们构建一个 PATH 字符串,然后使用此路径字符串对节点进行排序:

WITH CTE AS
(
   SELECT ParentID, CommentID, UserName, CommentDateTime,
          ParentID as ThreadID,
          CAST(ParentID as varchar(MAX)) as PathStr
   FROM T 
   WHERE CommentID = T.ParentID 

   UNION ALL

   SELECT T.ParentID, T.CommentID, T.UserName, T.CommentDateTime,
          CTE.ThreadID,
          PathStr+'-'
          +CAST(T.CommentID as varchar(MAX)) as PathStr
   FROM T 
   JOIN CTE ON CTE.CommentID = T.ParentID
   WHERE T.CommentID <> T.ParentID 
)

SELECT * FROM CTE ORDER BY ThreadID,PathStr

我在示例表中添加了更多节点,所以结果如下:

╔══════════╦═══════════╦══════════╦═════════════════════════╦══════════╦═════════════╗
║ ParentID ║ CommentID ║ UserName ║     CommentDateTime     ║ ThreadID ║   PathStr   ║
╠══════════╬═══════════╬══════════╬═════════════════════════╬══════════╬═════════════╣
║       58 ║        58 ║ Vicky    ║ 2016-12-02 11:51:07.270 ║       58 ║ 58          ║
║       58 ║        61 ║ Billu    ║ 2016-12-02 12:35:40.220 ║       58 ║ 58-61       ║
║       61 ║        63 ║ Rakesh   ║ 2016-12-02 13:37:42.133 ║       58 ║ 58-61-63    ║
║       58 ║        62 ║ Rakesh   ║ 2016-12-02 12:37:42.133 ║       58 ║ 58-62       ║
║      158 ║       158 ║ Vicky    ║ 2016-12-02 11:51:07.270 ║      158 ║ 158         ║
║      158 ║       161 ║ Billu    ║ 2016-12-02 12:35:40.220 ║      158 ║ 158-161     ║
║      161 ║       163 ║ Rakesh   ║ 2016-12-02 13:37:42.133 ║      158 ║ 158-161-163 ║
║      161 ║       164 ║ Rakesh   ║ 2016-12-02 13:37:42.133 ║      158 ║ 158-161-164 ║
║      158 ║       162 ║ Rakesh   ║ 2016-12-02 12:37:42.133 ║      158 ║ 158-162     ║
╚══════════╩═══════════╩══════════╩═════════════════════════╩══════════╩═════════════╝

【讨论】:

  • Valex,是的,我只需要像 CTE 这样的查询,我可以在其中显示如上所示的值。我集成了您的代码,但结果为空白。如果您使用此链接“stackoverflow.com/review/suggested-edits/14271418”,我在其中问了第一个问题以显示父母下的孩子并得到答案。现在的问题是,如果新用户在父级之下,他的评论将在父级之下。您也可以在给定的链接中获取表结构。
  • @Vikash:我猜它是空白的,因为帖子树的结构不一样。在这个(当前)问题中,一个起始帖子有一个指向自身的链接(58,58)。在较早的问题中,开始帖子已改为replycommentIId = NULL。所以只要正确可以回答和改变两个条件WHERE CommentID = T.ParentID => WHERE CommentID IS NULL 和第二个条件WHERE T.CommentID &lt;&gt; T.ParentID => WHERE T.CommentID IS NOT NULL。这会有所帮助。
  • 我已经从上一个问题中编辑了我的问题,因为链接在上面的评论中。请仔细检查并给我解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 2011-03-28
  • 1970-01-01
  • 2012-07-18
相关资源
最近更新 更多