SQL Server 2008和子集的匹配

时间:2012-02-17 15:30:10

标签: sql-server-2008 set

我正在使用SQL Server 2008,我需要匹配多组部件。这些部件可以包含其他部件(非递归以使其更容易)。

表格部分

PartId ...
1
2
3
30
40
50
60
70

表PartRelation

PartIdMother PartIdChild (non recursive)
1            30
1            40
1            50
1            60

2            30
2            40

3            30
3            40
3            50

现在我有一组随机部件,我想知道这可能是哪个聚合部件。

表PartRandom

Id     PartId
1      30
2      40
3      70

显然,第1,2和3部分将匹配第1行和第2行。查询的预期结果将是这样的:

预期结果

Id     PartId  PartIdMother
1      30      1
2      40      1

1      30      2
2      40      2

1      30      3
2      40      3

我在这里完全封锁了。请分享您的智慧,最大限度地利用SQL 2008。最重要的是表PartRelation中的递归关系的支持。

这是SQL代码:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id =
OBJECT_ID(N'[dbo].[Part]') AND type in (N'U'))
DROP TABLE [dbo].[Part]
GO
CREATE TABLE [dbo].[Part]( [PartId] [int] NOT NULL,
CONSTRAINT [PK_Part] PRIMARY KEY CLUSTERED ([PartId] 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
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (1)
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (2)
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (3)
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (30)
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (40)
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (50)
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (60)
INSERT INTO [Area51].[dbo].[Part] ([PartId]) VALUES (70)
GO
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id =
OBJECT_ID(N'[dbo].[PartRelation]') AND type in (N'U'))
DROP TABLE [dbo].[PartRelation]
GO
CREATE TABLE [dbo].[PartRelation]([PartIdMother] [int] NOT NULL,
[PartIdChild] [int] NOT NULL,
CONSTRAINT [PK_PartRelation] PRIMARY KEY CLUSTERED
( [PartIdMother] ASC, [PartIdChild] 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
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(1, 30)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(1, 40)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(1, 50)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(1, 60)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(2, 30)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(2, 40)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(3, 30)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(3, 40)
INSERT INTO [Area51].[dbo].[PartRelation]([PartIdMother],[PartIdChild]) VALUES(3, 50)
GO
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id =
OBJECT_ID(N'[dbo].[PartRandom]') AND type in (N'U'))
DROP TABLE [dbo].[PartRandom]
GO
CREATE TABLE [dbo].[PartRandom](
[Id] [int] NOT NULL,
[PartId] [int] NULL,
CONSTRAINT [PK_PartRandom] 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
INSERT INTO [Area51].[dbo].[PartRandom]([Id],[PartId]) VALUES (1, 30)
INSERT INTO [Area51].[dbo].[PartRandom]([Id],[PartId]) VALUES (2, 40)
INSERT INTO [Area51].[dbo].[PartRandom]([Id],[PartId]) VALUES (3, 70)

1 个答案:

答案 0 :(得分:1)

尝试:

select ra.Id, ra.PartId, re.PartIdMother
from PartRandom ra
join PartRelation re on ra.PartId = re.PartIdChild

- 返回任何子部件在PartRandom中的父部件。

编辑:对于递归版本,请尝试:

;with cte as 
(select PartIdMother PartIdAncestor, PartIdChild from PartRelation r
 where not exists (select null from PartRelation r1 where r1.PartIdChild = r.PartIdMother)
/* remove where not exists condition to select all intermediate levels */
 union all
 select c.PartIdAncestor, r.PartIdChild 
 from cte c
 join PartRelation r on c.PartIdChild = r.PartIdMother)
select ra.Id, ra.PartId, re.PartIdAncestor
from PartRandom ra
join cte re on ra.PartId = re.PartIdChild