複数のキーワードをどのように接続するかを決定する必要があります。誰かが検索で「keyword1 keyword2」と入力した場合、同じ写真に関連付けられる両方のキーワードを探しているか (AND 演算)、同じ写真に関連付けられているいずれか (または両方) のキーワードを探しているか (OR手術)。両方を提供するのはどうですか?そして、「このキーワードで、他のキーワードではない」などはどうでしょう...
ディスク領域の消費以外に、WordID 列が何を提供するのかはわかりません。列として「WordID、Word」を含むテーブルがあり、相互参照テーブルに「PhotoID、WordID」列がある場合、1 つの実用的な設計になります。別の賢明なデザインには、「PhotoID、Word」があります。「WordID、PhotoID、Word」を含むテーブルを持つことは特に賢明ではありません。動作しますが、WordID 列は実質的に使用されていません。そのテーブルで繰り返しがないようにするには、PhotoID と Word の組み合わせに一意の制約が必要です。
@Words (一時) テーブルを指定すると、これを実行して AND オプションを取得できます。
SELECT P.PhotoID, P.Name, P.Title, P.Description
FROM Photo P, Word2Photo W
WHERE P.PhotoID = W.PhotoID
GROUP BY P.PhotoID, P.Name, P.Title, P.Description
HAVING COUNT(*) = (SELECT COUNT(*) FROM @Words L, Word2Photo M
WHERE M.Word = L.Word
AND M.PhotoID = P.PhotoID
)
Word2Photo テーブルのエントリ数が、特定の写真の @Words テーブルのエントリ数と同じであることを確認します。これは相関サブクエリです。効率的ではありませんが、効果的です。便利なことは、ほとんどの場合 OR オプションで構造を繰り返すことができることです。
SELECT P.PhotoID, P.Name, P.Title, P.Description
FROM Photo P, Word2Photo W
WHERE P.PhotoID = W.PhotoID
GROUP BY P.PhotoID, P.Name, P.Title, P.Description
HAVING 1 <= (SELECT COUNT(*) FROM @Words L, Word2Photo M
WHERE M.Word = L.Word
AND M.PhotoID = P.PhotoID
)
これは、単語リスト内の単語の少なくとも 1 つを含む写真を探します。
他にも方法はあると思いますが、対称性は魅力的です。明らかに、より複雑な基準 (AND と OR の混合、または NOT の追加) に入ると、構造が変化します。
警告
テストされていないコード。