2012-03-19 3 views
0

私は、多対多の関係を持つ単純なSQLリレーショナルモデルを持っています。ここ成分表は、私がobject2のセットに共通するすべてのobject1を知っていただきたいと思いコンポジションテーブルの交叉方法

 
___________________________ 
| object1_id | object2_id | 
|---------------------------| 

です。私の基本的な気持ちは、この

SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_1> 
INTERSECT 
SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_2> 

のような要求を行うことであると私は、セット内のN個のオブジェクト2を持っている場合、私はN INTERSECT

SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_1> 
INTERSECT 
SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_2> 
... 
INTERSECT 
SELECT c.object1_id FROM composition c WHERE c.object2_id = <given_id_N> 

をやるしかし、それは非常に最適化され見えません。手伝って頂けますか ?私は本当にSQLの専門家ではない。私はそれをするためにJOINを使うことができると思う。

サンプル

 
___________________________ 
| object1_id | object2_id | 
|---------------------------| 
|   10 |   1 | 
|   11 |   1 | 
|   10 |   2 | 
|   12 |   2 | 
|   10 |   3 | 
|   11 |   3 | 
|   13 |   3 | 

  • {object2_id組} =>
  • {1、2} => {10}
  • {{object1_id期待} 1、3} => {10,11}
  • {1、2、3} => {10}

答えて

2

パフォーマンス面では問題はないようです。本当に問題があるかどうか調べましたか? 6が提供するIDの数であることを

SELECT object1_id 
FROM composition 
WHERE object2_id IN (id1, id2, ..., id6) 
GROUP BY object1_id 
HAVING COUNT(*) = 6 

注:(object1_id, object2_id)が一意である場合は、次のよう

することは、あなたはもっと簡潔にクエリを記述することができます。これは、異なる数のIDが提供される場合に変更する必要があります。これがスピードを上げるかどうかを確認するには、ダダの実際のパフォーマンスを測定する必要があります。

あなたが一意性を仮定できない場合

が、これは動作するはずです:

SELECT object1_id 
FROM composition 
WHERE object2_id IN (id1, id2, ..., id6) 
GROUP BY object1_id 
HAVING COUNT(DISTINCT object2_id) = 6 

最も重要なことは、しかし、あなたのテーブルの上に適切なインデックスを持っていることを確認することです!これは、遠くのよりも重要です。

+0

多くのお役に立てていただきありがとうございます。クエリの複雑さはO(N)と今はO(1)です(なぜなら、2つ以上のオブジェクトを交差させるからです)。もう一度ありがとうございました –

1

これはうまくいくと思います。それは、一致する組成2も有する全ての組成1を見つける。あなたが探しているものを誤解していない限り。もしそうなら、いくつかのサンプルデータを提供できますか?

SELECT c1.object_id 
FROM Composition AS c1 
WHERE EXISTS 
    (
     SELECT 1 
     FROM Composition c2 
     WHERE c2.object2_id = c1.object1_id 
     --Add an AND to only look for a certain set of c2's 
     --AND c2.object2_id IN (SET of object2id's) 
    ) 
+0

私はサンプルとサンプルを追加しました。あなたのクエリは私の場合にはうまくいかないと思います。私はobject2_id == object1_idは必要ありません。 –

0

私はこれがrelational division質問だと思います。

類推:すべての部品を供給するサプライヤを見つける。

object2_idpart_id

object1_idあるクエリが

part_id{ 1, 2, 3 }のセット内のすべての部品を供給サプライヤーのためsupplier_id値を検索し、あるsupplier_id

です。

これは通常で修飾され、

...少なくとも一部と...を供給サプライヤー

そうでない場合は、すべてのサプライヤーが部品の空のセットを提供します。

+0

この回答を下落させる人は、問題を解決できないという関係分裂の証拠を投稿してください。受け入れられる答えは、古典的な除算パターンのように見えますが、除数セットの基数のハードコード化された値、つまり縮尺されません。ありがとう;) – onedaywhen

+0

正解ですが、コンセプトに名前をつけてリンクを付けるだけであれば、この分野では大したことはありません。多分それが理由でした。 –

+0

@ErwinSmout:あなたは正しいと思います! – onedaywhen

関連する問題