我正在使用SQL Server 2008,我需要匹配多组部件。这些部件可以包含其他部件(非递归以使其更容易)。
PartId ...
1
2
3
30
40
50
60
70
PartIdMother PartIdChild (non recursive)
1 30
1 40
1 50
1 60
2 30
2 40
3 30
3 40
3 50
现在我有一组随机部件,我想知道这可能是哪个聚合部件。
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)
答案 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