SQL Server 2008 и сопоставление подмножеств - PullRequest
1 голос
/ 17 февраля 2012

Я работаю с 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.На высшем уровне будет поддержка рекурсивных отношений в Table 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 Ответ

1 голос
/ 17 февраля 2012

Попробуйте:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...