2

FooとBarの2つのテーブルがあるとします。FoosとBarsの間の多対多の関係のために、関連付けテーブルFoo_Barがあります。

ここで、基本的に、動的な数のBar制約に一致するFoosを選択するクエリが必要です。これを行うには、適切な数の結合を使用してクエリを動的に生成します。

SELECT *
FROM Foo F INNER JOIN
     Foo_Bar FB1 ON FB1.FooId = F.Id AND FB1.BarId= Y INNER JOIN
     Foo_Bar FB2 ON FB2.FooId = F.Id AND FB2.BarId= Z INNER JOIN
     --one inner join for each constraint

もっと簡単な方法があるのだろうかと思います。基本的に次のようなクエリが必要です。

SELECT *
FROM Foo F
WHERE (Y, Z, ...) IN (SELECT BarId FROM Foo_Bar WHERE FooId = F.Id)

もちろん、これは有効なSQLではありませんが、動的クエリが目的の結果を達成するための唯一の合理的に移植可能な方法であるかどうか疑問に思っています。

4

2 に答える 2

1

関係分割クエリが必要だと思います。これを行う多くの方法でこの質問を参照してください: How to filter SQL results in a has-many-through relationship

@Erwin の回答 (Postrgres 用) にもパフォーマンス テストがあり、動的な方法 (多くの結合、多くのEXISTSサブクエリ、または多くのINサブクエリを使用) は、変数テーブルまたはリストのみを使用した静的クエリよりも高速に実行されることがわかります。

ただし、データを使用してサーバーでテストしてください。たとえば、MySQL にはINサブクエリに関するパフォーマンスの問題があるため、バージョンを使用するとパフォーマンスが向上することが期待されJOINます。

テーブルで翻訳された「Erwin 1」クエリは次のとおりです。

SELECT f.*
FROM   Foo f
JOIN   (
   SELECT FooId 
   FROM   Foo_Bar
   WHERE  BarId IN (Y, Z, ...)               --- your list or table here
   GROUP  BY FooId
   HAVING COUNT(*) = @N                      --- the size of this list or table
   ) fb ON fb.FooId = f.Id;
于 2012-06-20T23:25:46.583 に答える
1

あなたが提供した情報に基づいて、次のクエリは必要なデータを取得します。

SELECT *
FROM Foo F INNER JOIN
     Foo_Bar FB ON FB1.FooId = F.Id
WHERE FB.BarId IN (Y, Z, ...)
于 2012-06-20T22:54:50.440 に答える