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表。每个术语都属于一个分类法,分类法可以是包容性的(意味着可以应用该分类法中的多个术语)或排他性的(意味着该分类法中的术语是互斥的,只有一个可以适用)。

表关系是这样的:

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 回答