2012-02-17 10 views
1

SQL Server 2008を使用していますが、私はパーツのセットを一致させる必要があります。これらのパーツには、他のパーツを含めることができます(再帰的ではありません)。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の再帰的関係のサポートになります。

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

ので、私はそれが期待される結果への関与が何に明確ではありませんよ。 –

+0

ご返信ありがとうございます。 PartRandomのパーツが本当にランダムであることを示すだけです。それ以外の場合は、PartRelation内の既存のサブセットのサブセットのみを含むと考えるのは間違いです。 – Frankenstein

答えて

1

試してみてください: - 子部品のいずれかがPartRandomである親部品を返すために

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

ここ

は、SQLコードです。

EDIT:再帰バージョンについては、してみてください: `70`のみPart`と` `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 
+0

ありがとう、私はそれだと思います。うわー、私の頭には結び目がありました。あなたは再帰が同様に簡単だろうと思いますか? – Frankenstein

+0

@Frankenstein:可能な再帰的クエリの更新された回答を参照してください。 –

+0

これは美しく、エレガントでシンプルなソリューションです。 SQL Server 2008のCommon Table Expressionsについてもっと知る必要があります。ありがとうございます。 – Frankenstein