2012-02-23 10 views
1

を決定するために、クエリをEXISTS:SQL Serverは、私は以下の表を持っている関係

フー

FooId INT PRIMARY KEY 

FooRelationship

FooRelationshipId INT PRIMARY KEY IDENTITY 
    FooParentId INT FK 
    FooChildId INT FK 

どのように私はすべて戻ってくるクエリを記述しますFooのIDとステータス(レコードが親、子、どちらでもない)

ルール:

  • fooが、親や子供やでもないだろう。
  • fooは、複数の異なるfoosの親になることができます。
  • fooは複数のfooの子になることはできません。

私はもともとこのクエリを書いた:

SELECT 
    FooId, 
    CASE 
     WHEN Parent.FooRelationshipId IS NOT NULL THEN 'Parent' 
     WHEN Child.FooRelationshipId IS NOT NULL THEN 'Child' 
     ELSE 'Neither' 
    END 
FROM Foo F 
LEFT JOIN FooRelationship Parent ON F.FooId = Parent.FooParentId 
LEFT JOIN FooRelationship Child ON F.Fooid = Child.FooParentId 

これはfooが他の二つのFOOSへの親であるためならば、それはその倍のIDを返します壊れています。

これを再利用して結合を使用したり、EXISTSなどを使用したりすることはできません。

答えて

2

ちょうどDISTINCTを使用してください - これは良い使用例です。あなたが実際に両方のテーブルからデータを取得する必要があるので、あなたはEXISTSを使用することはできません。

SELECT DISTINCT 
    FooId, 
    CASE 
     WHEN Parent.FooRelationshipId IS NOT NULL THEN 'Parent' 
     WHEN Child.FooRelationshipId IS NOT NULL THEN 'Child' 
     ELSE 'Neither' 
    END 
FROM Foo F 
LEFT JOIN FooRelationship Parent ON F.FooId = Parent.FooParentId 
LEFT JOIN FooRelationship Child ON F.Fooid = Child.FooParentId 

しばしば厄介なデータを隠すために使われているので、私は通常、DISTINCTの大ファンではないんだけど、私はこれがあると思いますそのための適切な使用。

大量のフィールドと行にわたって使用すると、処理が大幅に遅くなる可能性があることに注意してください。

あなただけのこれらの値を取得し、その後、同様の行の残りの部分を移入する場合は、リレーションシップ・ロジックのための副問合せを行うことができます。

SELECT s.FooID, s.Relationship, T.* 
FROM Table T 
INNER JOIN (SELECT DISTINCT 
    FooId, 
    CASE 
     WHEN Parent.FooRelationshipId IS NOT NULL THEN 'Parent' 
     WHEN Child.FooRelationshipId IS NOT NULL THEN 'Child' 
     ELSE 'Neither' 
    END as [Relationship] 
    FROM Foo F 
    LEFT JOIN FooRelationship Parent ON F.FooId = Parent.FooParentId 
    LEFT JOIN FooRelationship Child ON F.Fooid = Child.FooParentId) s 
ON s.FooId = t.FooID 
+0

このクエリを書くより良い方法はありますか?このテーブルにはかなりの数の行があり、それは約30〜40列あるので、私はパフォーマンスについて心配していますか? – Dismissile

+0

@Dismissile私はより多くの情報が必要ですが、1つのオプションは、副選択としてあなたのサンプル(狭い)クエリを使用し、その上でJOINすることです。次に、 'FooID、Relationship'情報を残りの行を取得せずに取得し、' JOIN'を実行します。私は例を投稿します。 – JNK

+0

ありがとうございました。 – Dismissile

0

SELECT DISTINCT FooID, ...

にそれを使用しようとします1つだけ返してください

+0

' FooID'だけでなく、行の値の一意的な組み合わせごとに1つの行しか返しません – JNK

0

selectの代わりにselect distinctを実行するように既存のクエリを変更してください。

関連する問題