我有以下一套直接&间接文档依赖关系(按类型):
无论是否插件,我都需要生成ENTIRE依赖关系链的包含列表。
例如
保持中期其他记录可能存在,我不想包括:
我不确定发布我的代码是否有价值,因为它不起作用。但是,如果你想...我愿意。
SETUP:
以下是本地设置的代码...
/****** Object: Table [dbo].[Document] Script Date: 2/13/2018 9:15:57 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Document](
[Id] [int] NOT NULL,
[ParentId] [int] NULL,
CONSTRAINT [PK_dbo.Document] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[DocumentDependency] Script Date: 2/13/2018 9:15:57 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[DocumentDependency](
[DocumentId] [int] NOT NULL,
[DependencyId] [int] NOT NULL,
[DependencyTypeName] [varchar](100) NOT NULL,
CONSTRAINT [PK_dbo.DocumentDependency] PRIMARY KEY CLUSTERED
(
[DocumentId] ASC,
[DependencyId] ASC,
[DependencyTypeName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
INSERT [dbo].[Document] ([Id], [ParentId]) VALUES (1, NULL)
GO
INSERT [dbo].[Document] ([Id], [ParentId]) VALUES (2, 1)
GO
INSERT [dbo].[Document] ([Id], [ParentId]) VALUES (3, 2)
GO
INSERT [dbo].[Document] ([Id], [ParentId]) VALUES (4, NULL)
GO
INSERT [dbo].[Document] ([Id], [ParentId]) VALUES (5, 4)
GO
INSERT [dbo].[Document] ([Id], [ParentId]) VALUES (6, 5)
GO
INSERT [dbo].[Document] ([Id], [ParentId]) VALUES (7, 5)
GO
INSERT [dbo].[DocumentDependency] ([DocumentId], [DependencyId], [DependencyTypeName]) VALUES (2, 1, N'DeviceAffinity')
GO
INSERT [dbo].[DocumentDependency] ([DocumentId], [DependencyId], [DependencyTypeName]) VALUES (3, 1, N'DeviceAffinity')
GO
INSERT [dbo].[DocumentDependency] ([DocumentId], [DependencyId], [DependencyTypeName]) VALUES (5, 4, N'DeviceAffinity')
GO
INSERT [dbo].[DocumentDependency] ([DocumentId], [DependencyId], [DependencyTypeName]) VALUES (6, 4, N'DeviceAffinity')
GO
INSERT [dbo].[DocumentDependency] ([DocumentId], [DependencyId], [DependencyTypeName]) VALUES (7, 6, N'DeviceAffinity')
GO
ALTER TABLE [dbo].[Document] WITH CHECK ADD CONSTRAINT [FK_dbo.Document_dbo.Document_ParentId] FOREIGN KEY([ParentId])
REFERENCES [dbo].[Document] ([Id])
GO
ALTER TABLE [dbo].[Document] CHECK CONSTRAINT [FK_dbo.Document_dbo.Document_ParentId]
GO
ALTER TABLE [dbo].[DocumentDependency] WITH CHECK ADD CONSTRAINT [FK_DocumentDependency_Document] FOREIGN KEY([DocumentId])
REFERENCES [dbo].[Document] ([Id])
GO
ALTER TABLE [dbo].[DocumentDependency] CHECK CONSTRAINT [FK_DocumentDependency_Document]
GO
ALTER TABLE [dbo].[DocumentDependency] WITH CHECK ADD CONSTRAINT [FK_DocumentDependency_Document1] FOREIGN KEY([DependencyId])
REFERENCES [dbo].[Document] ([Id])
GO
ALTER TABLE [dbo].[DocumentDependency] CHECK CONSTRAINT [FK_DocumentDependency_Document1]
GO
答案 0 :(得分:1)
首先,您需要一个递归CTE来获取填充列表。这是一种方法:
with cte as (
select t.documentId, t.dependencyId, t.documentId as top_id
from t
where dependencyId is null
union all
select t.documentId, t.dependencyId, cte.top_id
from cte join
t
on cte.dependencyId = t.documentId
)
select * from CTE
接下来,您可以查找所需的ID:
with cte as (
select t.documentId, t.dependencyId, t.documentId as top_id
from t
where dependencyId is null
union all
select t.documentId, t.dependencyId, cte.top_id
from cte join
t
on cte.dependencyId = t.documentId
)
select *
from cte
where cte.top_id = (select cte2.top_id from cte cte2 where cte2.documentId = ?);
答案 1 :(得分:1)
您可以使用此
DECLARE @Id INT = 7
;WITH CTE AS (
SELECT *, RN = ROW_NUMBER() OVER(ORDER BY DocumentId) FROM [DocumentDependency]
),
CTE1 AS (
SELECT *, RN AS RL FROM CTE
UNION ALL
SELECT T.*, CTE1.RL FROM CTE T
INNER JOIN CTE1 ON (CTE1.DependencyId IN ( T.DependencyId, T.DocumentId ) OR CTE1.DocumentId IN ( T.DependencyId, T.DocumentId ) )
AND T.RN > CTE1.RN
)
, CTE2 AS
(
SELECT * FROM CTE1 WHERE RL =
(SELECT MIN (RL) FROM CTE1 WHERE DependencyId = @Id or DocumentId = @Id)
)
SELECT DocumentId FROM CTE2
UNION
SELECT DependencyId FROM CTE2
@Id = 7的结果:
DocumentId
-----------
4
5
6
7
@Id = 2的遗漏:
DocumentId
-----------
1
2
3