2012-02-14 7 views
1

これは一般的な設定です。行に外部キーを持つ別の表のN行があるかどうかを照会するにはどうすればよいですか?

私はテーブルCardsAttributesとそれらの間の結合テーブルを持っています。 (のは、それTagsを呼ぶことにしましょう。それは含まれていCardIDAttributeID。)Attributesテーブルがあり、ほとんど私がしているすべてのカードを照会するに行くかどうなどHasPowerIsPoisonousImmuneToWater

としてだけで説明の両方IsPoisonousIsElectric?既にIDが13と45のIDを持っていると仮定しましょう。つまり、技術的にはAttributesテーブルはこのSQLの一部である必要はありません。私はこれのようなものを作りましたが、それが最適かどうかはわかりません。

SELECT *, (COUNT * FROM Tags t WHERE t.CardID = c.CardID AND t.AttributeID IN (13, 45)) AS TagCount 
FROM Cards c 
WHERE TagCount = 2 

私の質問が意味をなさないことを願います。基本的には、Web UIを見ていると想像してください。あなたは〜5000枚のカードを拾い読みしており、あなたの結果を絞りたいと思っています。だから、あなたは "毒"、 "電気"、 "水に免疫"などのチェックボックスを始めます。その結果は、それらの属性に基づいてフィルタリングされます。

思考?あなたは、複数の結合を使用できますが

答えて

3
SELECT * 
FROM Cards 
WHERE (Cards.Id IN (
    SELECT DISTINCT CardID 
    FROM Tags 
    WHERE AttributeID IN (13, 45) 
    GROUP BY CardID 
    HAVING (COUNT(AttributeID) >= 2) 
)) 

インナークエリは、属性の少なくとも二つを持っているCardIDsをフェッチあなたが指定したのだ、そして外側のクエリで実際のカードデータをフェッチするためにフィルタとしてその結果を使用しています。

+0

これはかなり簡単です。私はそれが何をしているのか理解している。あなたはそれが上方に拡大するにつれてパフォーマンスの問題があると思いますか?私が心配しているのは、私が働いているカードのプールが実際には成長していないからです。ただ、それを他の/より大きなカードプールに展開することを心配しています。 – TheBuzzSaw

+0

と適切なインデックス付けがある場合は、フィルタリングするために500以上の属性を渡していない限り、これはかなり良好に調整する必要があります。 –

+0

ああ間違いなく。私は、極端な場合には、ユーザーが12の属性を渡す可能性があると思いますか?このトピックについては、非PK列のインデックス作成を有効にすることをお勧めしますか? – TheBuzzSaw

1

は、私は、属性が単純にカードの表の列になるように、あなたのDBを再設計をお勧めします。

+0

大抵の場合NULL列を持つ広大なテーブルを作成することをお勧めしますか? – TheBuzzSaw

+0

いくつ(BIT)列ですか? –

+0

私は約2/3がビット列で、1/3は数値属性であると言います。 (私は 'Tags'に 'Amount'カラムを追加しようとしていました) – TheBuzzSaw

関連する問題