2

私はSQLの初心者で、少し複雑なクエリを実行する方法を理解しようとしています。Rails 3アプリで作業しているので、写真と用語の間には多対多の関係があります。セットアップはかなりバニラです:

photos: id

terms: id

photos_terms: photo_id | term_id

私ができるようにしたいのは、任意の用語グループの中からANDとORの一致を見つけることです。したがって、たとえば、疑似SQLでは次のようになります。

Select Photos where Term ID in (1 or 2) and (3 or 4 or 5) and (6).

どうすればそのようなクエリを書くことができますか?参考までに、PostgreSQLを使用しています。


更新ルーベンスの回答に応えて、グループ化を説明するのに役立つ可能性のあるもう少し情報がありますが、以前は関連していたかどうかはわかりませんでした。

別のモデル、分類法があるので、taxonomies表。各用語は分類法に属し、分類法は包括的(その分類法の複数の用語が適用される可能性があることを意味します)または排他的(その分類法の用語は相互に排他的であり、1つだけが適用できることを意味します)のいずれかになります。

テーブルの関係は次のようになります。

terms: id | taxonomy_id

taxonomy: id | inclusive(boolean)

グループ化は、さまざまな分類法からの用語になります。各グループ化には常にAND一致が必要です。包括的分類法の用語間でAND一致が必要であり、排他的分類法の用語間でOR一致が必要です。

別の擬似コードの例を示すために、次の場合:

Taxonomy: Color (inclusive = true)
Terms: Red, Blue, Green

Taxonomy: Location (inclusive = false)
Terms: NY, NJ, PA, MD

私はこのようにクエリしたいかもしれません:

Photos where terms in (red and blue) and (NY or NJ).

それは理にかなっていますか?FWIWの用語は、高度に構造化されたタグと同じです。

4

2 に答える 2

3

あなたはおそらく次のようなものが欲しいでしょう

SELECT photo_id FROM photos JOIN photos_terms ON (photos.id = photo_id)
WHERE term_id IN (1,2,3,4,5,6)
GROUP BY photo_id
HAVING
 bool_or(term_id IN (1,2))
 AND bool_or(term_id IN (3,4,5))
 AND bool_or(term_id = 6)

(条件はオプションですが、処理速度が上がる可能性があります)。

于 2012-11-25T17:33:01.907 に答える
2
SELECT * FROM photos p
WHERE 1=1
AND EXISTS ( SELECT * FROM photos_term pt
    WHERE pt.photo_id = p.id AND term_id IN (1,2)
    )
AND EXISTS ( SELECT * FROM photos_term pt
    WHERE pt.photo_id = p.id AND term_id IN (3,4,5)
    )
AND EXISTS ( SELECT * FROM photos_term pt
    WHERE pt.photo_id = p.id AND term_id IN (6)
    )
    ;
于 2012-11-25T17:48:26.083 に答える