SQL 服务器:分组分层数据
SQL Server: Grouping heirarchical data
我有一份文件 table - 参见下面的定义
在这个 table 中,我们有一个根文档,它的 OriginalDocID
为 null
每次进行修订时都会添加一个新条目,父条目 documentID
作为 OriginalDocID
我想要做的是能够 group/partition 原始文档周围的所有内容 OriginalDocID
为 null
每个文档可以从一个起点进行多次修订。
意味着我们可以
Doc Id 1 -> 2 -> 3
2 -> 8 -> 9
1 -> 4 -> 7
5 -> 10
所以我希望看到的是根文档的所有行。附加
我希望这是有道理的。对于我的一生,我无法解决足够的问题。
CREATE TABLE [dbo].[Document](
[DocumentID] [int] IDENTITY(1,1) NOT NULL,
[DocumentName] [varchar](max) NOT NULL,
[ContentType] [varchar](50) NULL,
[DocumentText] [varchar](max) NULL,
[DateCreated] [datetime] NULL,
[DocumentTypeId] [int] NULL,
[Note] [varchar](8000) NULL,
[RefID] [int] NULL,
[Version] [int] NULL,
[Active] [bit] NULL,
[OriginalDocID] [int] NULL
)
您需要使用递归 CTE 来执行此操作。这是一个返回自身的查询,因此它可以遍历层次结构并在向下(或向上)该层次结构的级别工作时收集信息。
在你的情况下,类似于:
WITH RECURSIVE docCTE AS
(
/* Recursive Seed */
SELECT
cast(null as int) as parentdoc
documentID,
0 as depth,
documentid as originalDocument,
CAST(null as varchar(100) as docpath
FROM
dbo.document
Where originalDocID IS NULL
UNION ALL
/* Recursive Term */
SELECT
docCTE.DocumentID as parentdoc,
document.documentID,
depth + 1 as depth,
docCTE.originalDocument,
docCTE.Path + '>' + document.documentID
FROM
docCTE
INNER JOIN dbo.document on doccte.document = document.originalDocID
WHERE
depth <= 15 /*Keep it from cycling in case of bad hierarchy*/
)
SELECT * FROM docCTE;
递归 CTE 由两部分组成。
递归种子,这是我们用来启动查询的。这是originalDocID为空的所有文档记录。
递归项,我们将 table 连接回建立 parent/child 关系的递归 CTE。
在您的情况下,我们将递归种子中的 documentid 捕获为 originalDoc
,这样我们就可以在开始遍历文档的层次结构时通过找到的每条记录取下来。
刚开始时这些可能有点让人不知所措,但写几次后,它就是第二天性(当你遇到更多此类数据时,你会发现真的很有帮助)。
我有一份文件 table - 参见下面的定义
在这个 table 中,我们有一个根文档,它的 OriginalDocID
为 null
每次进行修订时都会添加一个新条目,父条目 documentID
作为 OriginalDocID
我想要做的是能够 group/partition 原始文档周围的所有内容 OriginalDocID
为 null
每个文档可以从一个起点进行多次修订。
意味着我们可以
Doc Id 1 -> 2 -> 3
2 -> 8 -> 9
1 -> 4 -> 7
5 -> 10
所以我希望看到的是根文档的所有行。附加
我希望这是有道理的。对于我的一生,我无法解决足够的问题。
CREATE TABLE [dbo].[Document](
[DocumentID] [int] IDENTITY(1,1) NOT NULL,
[DocumentName] [varchar](max) NOT NULL,
[ContentType] [varchar](50) NULL,
[DocumentText] [varchar](max) NULL,
[DateCreated] [datetime] NULL,
[DocumentTypeId] [int] NULL,
[Note] [varchar](8000) NULL,
[RefID] [int] NULL,
[Version] [int] NULL,
[Active] [bit] NULL,
[OriginalDocID] [int] NULL
)
您需要使用递归 CTE 来执行此操作。这是一个返回自身的查询,因此它可以遍历层次结构并在向下(或向上)该层次结构的级别工作时收集信息。
在你的情况下,类似于:
WITH RECURSIVE docCTE AS
(
/* Recursive Seed */
SELECT
cast(null as int) as parentdoc
documentID,
0 as depth,
documentid as originalDocument,
CAST(null as varchar(100) as docpath
FROM
dbo.document
Where originalDocID IS NULL
UNION ALL
/* Recursive Term */
SELECT
docCTE.DocumentID as parentdoc,
document.documentID,
depth + 1 as depth,
docCTE.originalDocument,
docCTE.Path + '>' + document.documentID
FROM
docCTE
INNER JOIN dbo.document on doccte.document = document.originalDocID
WHERE
depth <= 15 /*Keep it from cycling in case of bad hierarchy*/
)
SELECT * FROM docCTE;
递归 CTE 由两部分组成。
递归种子,这是我们用来启动查询的。这是originalDocID为空的所有文档记录。
递归项,我们将 table 连接回建立 parent/child 关系的递归 CTE。
在您的情况下,我们将递归种子中的 documentid 捕获为 originalDoc
,这样我们就可以在开始遍历文档的层次结构时通过找到的每条记录取下来。
刚开始时这些可能有点让人不知所措,但写几次后,它就是第二天性(当你遇到更多此类数据时,你会发现真的很有帮助)。