Sql server 从一个表中的行按不同表中的关系排序生成值列表

Sql server 从一个表中的行按不同表中的关系排序生成值列表,sql-server,Sql Server,考虑下表: 应用程序 +----+-------------+---------+----------+ | id | previous_id | next_id | status | +----+-------------+---------+----------+ | 1 | NULL | 3 | Archived | +----+-------------+---------+----------+ | 3 | 1 | 4

考虑下表:

应用程序

+----+-------------+---------+----------+
| id | previous_id | next_id | status   |
+----+-------------+---------+----------+
| 1  |   NULL      |    3    | Archived |
+----+-------------+---------+----------+
| 3  |     1       |    4    | Archived |
+----+-------------+---------+----------+
| 4  |     3       |   NULL  | Approved |
+----+-------------+---------+----------+
评论

+-----+--------+----------------+
| id  | app_id |   comment      |
+-----+--------+----------------+
|  1  |   1    |  Testing       |
+-----+--------+----------------+
|  2  |   1    |  Still testing |
+-----+--------+----------------+
|  3  |   4    |  No longer     |
+-----+--------+----------------+
“应用程序”表包含应用程序的修订版。comments表包含应用程序每次迭代时留下的注释。它们通过以下方式连接在一起:

Applications.ID = Comments.APP_ID
有一个breadcrumb,它将告诉您应用程序是否有任何以前的修订,以及您是否正在处理当前的修订(当前行的下一个\u id值将始终为NULL)

我想做两件事

  • 一个应用程序有多少修订的计数。可能是零修订,也可能是16+修订
  • 任何给定当前应用程序(如ID=4)和所有以前应用程序的注释列表,按最新注释到最旧注释的顺序排列

  • 使用递归CTE,您可以为任何给定的应用程序构建修订列表。以下查询将为您提供按修订(最新优先)和注释id(最新优先)排序的修订/注释列表,由基本应用程序分隔。每行都有一个额外的计数列
    revision\u count
    重复,因此这都是在一个查询中完成的。请注意,修订计数是以0为基础的;也就是说,计数是基础的修订数,不包括基础。我相信这是您想要的。结果列
    revision
    是序列中基于1的修订号(1是最早的基本修订)

    当然,您可以根据需要进行推断或调整

    ;WITH Base AS
    (
        SELECT id, next_id, status, 1 AS revision
        FROM Applications
        WHERE previous_id IS NULL
    ), Revisions AS
    (
       SELECT id, next_id, status, revision, id AS BASEID
       FROM Base
       UNION ALL
       SELECT a.id, a.next_id, a.status, r.revision + 1 AS revision, r.BASEID
       FROM Applications a
       INNER JOIN Revisions r ON a.id = r.next_id
    ), RevisionCounts AS
    (
       SELECT COUNT(1) - 1 AS revision_count, BASEID
       FROM Revisions
       GROUP BY BASEID
    )
    SELECT r.BASEID, r.revision, r.id, r.status, c.comment, rc.revision_count
    FROM Revisions r
    LEFT OUTER JOIN Comments c ON c.app_id = r.id
    INNER JOIN RevisionCounts rc ON r.BASEID = rc.BASEID
    ORDER BY r.BASEID, r.revision DESC, c.id DESC 
    
    接下来,演示正在运行的查询。返回的数据为:

    BASEID REVISION ID STATUS COMMENT REVISION_COUNT 1 3 4 Approved No longer 2 1 2 3 Archived (null) 2 1 1 1 Archived Still testing 2 1 1 1 Archived Testing 2 BASEID修订ID状态注释修订\u计数 1 3 4已批准不再2 1 2 3存档(空)2 1存档的静态测试2 1存档测试2
    这很好,你现在有什么?我甚至不知道从哪里开始。我怀疑这完全可以用SQL完成,但我所做的任何事情都将是ColdFusion和SQL的奇怪组合。这太神奇了……正是我所寻找的。非常感谢!不客气。想了解更多递归CTE的人,请参阅 BASEID REVISION ID STATUS COMMENT REVISION_COUNT 1 3 4 Approved No longer 2 1 2 3 Archived (null) 2 1 1 1 Archived Still testing 2 1 1 1 Archived Testing 2